Hallo!
Ich habe eine art Legende, also ein Kästchen mit einem Pfeil, als custom shape erstellt, wobei der Pfeil außerhalb der Bounds des shapes gezeichnet werden soll. Hier der Code:
public sealed class Legend : Shape
{
public static readonly DependencyProperty ArrowLocationProperty = DependencyProperty.Register("ArrowLocation", typeof(Point), typeof(Legend), new FrameworkPropertyMetadata(new Point(-50, -50), FrameworkPropertyMetadataOptions.AffectsRender));
[TypeConverter(typeof(PointConverter))]
public Point ArrowLocation
{
get { return (Point)base.GetValue(ArrowLocationProperty); }
set { base.SetValue(ArrowLocationProperty, value); }
}
protected override Geometry DefiningGeometry
{
get
{
var r = new RectangleGeometry(new Rect(0, 0, Width, Height));
PathGeometry p = new PathGeometry();
p.Figures.Add(
new PathFigure(
new Point(20, 0),
new List<PathSegment> { new LineSegment(ArrowLocation, true), new LineSegment(new Point(0, 20), true) },
true
)
);
CombinedGeometry cg = new CombinedGeometry(GeometryCombineMode.Union, p, r);
return cg;
}
}
}
Ich benutze die Legende in einem Canvas:
<Window x:Class="LegendTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:LegendTest"
mc:Ignorable="d" WindowStartupLocation="Manual" WindowStyle="None" AllowsTransparency="True"
Title="MainWindow" Height="350" Width="525" Background="{x:Null}">
<Grid>
<Canvas x:Name="MainCanvas" ClipToBounds="False" Background="white">
<local:Legend x:Name="legend" Fill="Aquamarine" ArrowLocation="-50 -50" Width="100" Height="100" ClipToBounds="False" Canvas.Left="200" Canvas.Top="100" />
<local:Legend x:Name="legend2" Fill="Aquamarine" ArrowLocation="-50 -50" StrokeThickness="1" Stroke="Black" Width="100" Height="100" ClipToBounds="False" Canvas.Left="50" Canvas.Top="100" />
</Canvas>
</Grid>
</Window>
Das Ergebnis ist im Angang dargestellt: Die Legende ohne Rahmen wird richtig dargestellt. Die Legende mit Rahmen nicht (Pfeil fehlt). Im Designer werden beide Shapes korrekt dargestellt. Ich habe leider keine Ahnung was da schief läuft.
Ich will vor allem vorhandene CAD-Dateien laden (vorzugsweise DXF und DWG-Dateien) und anzeigen. Konstruieren muss ich nichts können, jedoch sollen die Dateien korrekt angezeigt werden.
Später will ich dem Anwender die Möglichkeit geben einfache Linien und Anmerkungen zur Zeichnung hinzuzufügen. Dass muss aber nicht notwendigerweise durch die Bibliothek verwirklicht sein.
Ich will das Ganze in WPF einsetzen, kann aber auch WinForms sein.
Früher hatte ich in meiner Software hierfür ein Imagenation-Plugin (das ist jetzt der OpenText Desktop Viewer). Das war allerdings sehr instabil (Abhängig vom verwendeten Dateityp) und langsam.
Hallo!
Ich suche eine möglichst freie oder kostengünstige Bibliothek zum Einbinden in meine Software, mit der man 2D CAD-Dateien darstellen und manipulieren kann.
Ich habe hierzu im Netz und im Forum leider noch nichts brauchbares gefunden.
Hat jemand schon einmal eine solche Bibliothek eingesetzt?
OK. Jetzt weis ich wenigstens, dass ich nicht grundlegend was falsch gemacht habe.
Da ich bereits alle ViewModels in meinen Anwendungen nach einem ähnlichen Muster aufgebaut habe, werde ich erst einmal bei meinem Workaround von oben bleiben.
Trotzdem Danke!!
Danke schonmal. Das funktioniert schon mal bei dem einfachen Beispiel.
In meiner Anwendung ist jedoch im Moment darauf angewiesen, dass die Eigenschaft CurrentEmployee im ViewModel bei der Aktualisierung gesetzt wird. Das geschieht in deiner Version jedoch auch nicht.
<DataGrid ItemsSource="{Binding Employees}" SelectedItem="{Binding CurrentEmployee}" AutoGenerateColumns="False" IsSynchronizedWithCurrentItem="True" CanUserAddRows="False" CanUserDeleteRows="False" IsReadOnly="True">
Meine Datenbindung der TextBox hatte übrigens funktioniert, bis ich die Validierung hinzugefügt habe.
OK. Anbei die stark vereinfachte Mini-Testanwendung.
Unterhalb des DataGrids habe ich eine Textbox, die den Namen des aktuell gesetzten Mitarbeiters aus dem ViewModel anzeigt.
Wenn im DataGrid einer ausgewählt wird, so erscheint er leider nicht, da im ViewModel gar keine Änderung am CurrentEmployee ankommt.
<Window.BindingGroup>
<BindingGroup>
<BindingGroup.ValidationRules>
<my:CompanyValidationRule />
</BindingGroup.ValidationRules>
</BindingGroup>
</Window.BindingGroup>
Wenn ich die Zeilen oben mit der BindingGroup auskommentiere, dann funktionierts.
Ich habe das Problem leider immer noch.
Als Workaround kann ich natürlich das SelectionChanged-Event des DataGrids verwenden, um mein ViewModel zu aktualisieren. Das ist aber nicht Sinn vom MVVM und außerdem Fehleranfällig.
private void DataGrid_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
(DataContext as CompanyViewModel).CurrentEmployee = (sender as System.Windows.Controls.DataGrid).SelectedItem as Employee;
}
Hat denn niemand eine Idee?
Hallo!
verwende MVVM um meine Formulare vom Code zu trennen.
Jetzt habe ich ein Fenster, in dem ein paar TextBoxen sind und ein DataGrid, welches eine Liste mit Objekten zeigt, die jedoch nicht bearbeitbar sein sollen. Sieht prinzipiell so aus:
<DataGrid ItemsSource="{Binding Employees}" SelectedItem="{Binding CurrentEmployee}" Grid.Row="1" AutoGenerateColumns="False" IsSynchronizedWithCurrentItem="True" CanUserAddRows="False" CanUserDeleteRows="False" IsReadOnly="True">
<DataGrid.Columns>
...
</DataGrid.Columns>
</DataGrid>
Das funktioniert auch, aber wenn ich in dem Formular eine BindingGroup hinzufüge, wird der "CurrentEmployee" in meinem ViewModel nicht mehr gesetzt.
<Window.BindingGroup>
<BindingGroup>
<BindingGroup.ValidationRules>
<helpers:CompanyValidationRule />
</BindingGroup.ValidationRules>
</BindingGroup>
</Window.BindingGroup>
Habe leider keine Ahnung an was das liegen könnte.
Hallo nochmal!
Hier mal meine gekapselte Mail-Funktion. So hat es bei einem ASP.NET-Projekt von mir funktioniert. Ich hatte kein SSL aktiviert.
public bool SendMail(string To, string from, string Subject, string BodyText)
{
MailMessage mail = new MailMessage();
try {
mail.To.Add(To.Trim());
mail.Subject = Subject;
mail.Body = BodyText;
mail.IsBodyHtml = true;
mail.From = new MailAddress(from);
SmtpClient mailClient = new SmtpClient("hostip");
mailClient.Port = 25;
mailClient.Credentials = new System.Net.NetworkCredential("username", "pw");
mailClient.Send(mail);
return true;
}
catch {
return false;
}
}
Das Thema gehört eigentlich nicht in das GUI-Forum.
Versuche mal als Absenderadresse eine Emailadresse anzugeben, mit der du empfangen kannst, dann solltest du Fehlermeldungen vom Empfänger-Emailserver zurück erhalten.
Der Code sollte normalerweise funktionieren. Habe ich so ähnlich auch schon gemacht.
Stimmt der Host? Bei mir war das smtp.googlemail.com
Habe folgende Lösung gefunden:
In einer Extension-Method werden alle Gruppen und Untergruppen rekursiv durchlaufen und der aktuelle Eintrag gesucht. Die Höhe der Zeilen und Gruppenüberschriften wird übergeben (Müssen überall gleich sein).
public static double GetRowY(this DataGrid grid, object o, double rowHeight, double groupHeaderHeight)
{
var myView = (CollectionView)CollectionViewSource.GetDefaultView(grid.ItemsSource);
if (myView != null) {
if (myView.Groups == null)
return rowHeight * (double)myView.IndexOf(o);
bool found = false;
double result = 0;
foreach (CollectionViewGroup gd in myView.Groups) {
result += groupHeaderHeight + getItemY(gd, o, rowHeight, groupHeaderHeight, out found);
if (found)
return result;
}
}
return -1;
}
private static double getItemY(CollectionViewGroup gd, object o, double rowHeight, double groupHeaderHeight, out bool found)
{
found = false;
if (gd.IsBottomLevel) {
if (gd.Items.Contains(o)) {
found = true;
return rowHeight * (double)gd.Items.IndexOf(o);
}
else
return rowHeight * (double)gd.Items.Count;
}
else {
double result = 0;
foreach (CollectionViewGroup g in gd.Items) {
if (found == false) {
result += groupHeaderHeight + getItemY(g, o, rowHeight, groupHeaderHeight, out found);
}
}
return result;
}
}
OK. Bin gerade selbst drauf gekommen was das Problem ist. PointFromScreen gibt die relative Position auf dem Bildschirm an. Wenn das DataGrid weniger Zeilen hat als angezeigt werden, ist das kein Problem, wenn es allerdings nach unten scrollen muss, ist der Abstand der letzten Zeile zur Oberkante des DataGrids auf dem Bildschirm immer gleich.
So geht's schon mal nicht.
Hallo!
Ich versuche gerade die Y-Position einer Zeile in einem DataGrid herauszufinden, da in relativ dazu eine Grafik ausrichten muss.
Gemeint ist also nicht der Index, sondern der Abstand der linken oberen Ecke der Zeile zum oberen Rand des DataGrids.
Folgendes habe ich schon erstellt:
public static DataGridRow GetRow(this DataGrid grid, Activity a)
{
int index = grid.Items.IndexOf(a);
if (index == -1)
return null;
DataGridRow row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
if (row == null) {
grid.UpdateLayout();
grid.ScrollIntoView(grid.Items[index]);
row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index);
}
return row;
}
private double getYOfActivity(Activity a)
{
var item = dataGrid.GetRow(a);
double y = 0;
if (item != null) {
Point newPoint = item.PointFromScreen(new Point(0, 0));
y = -newPoint.Y + dataGrid.PointFromScreen(new Point(0, 0)).Y;
}
return y;
}
Die DataGrid ist mit Activity-Objekten gefüllt. Leider liefert die FUnktion getYOfActivity(Activity a) für einige Activities gleiche Werte zurück, ohne dass ich ein Muster erkennen kann.
Hallo winSharp93,
das liegt wohl daran, dass das mein erstes größeres Projekt mit WPF ist 😉.
Mir war nicht klar, wie ich das Template an meine Objekte binden soll, die die Gruppierung definieren, da diese auch dynamisch erzeugt werden.
<ControlTemplate TargetType="GroupItem">
<Expander IsExpanded="True" Background="{Binding ???}" Foreground="Black" Name="expander">
<Expander.Header>
<TextBlock Text="{Binding Name}" FontWeight="Bold" />
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
public class GroupingDefinition : NotifyObject
{
private ActivityProperty property;
private Color color;
public GroupingDefinition(ActivityProperty property)
{
this.property = property;
}
public ActivityProperty Property
{
get
{
return this.property;
}
}
public Color Color
{
get
{
return this.color;
}
set
{
if (this.color != value) {
this.color = value;
OnPropertyChanged("Color");
}
}
}
}
Meine erste Idee war die Zeile mit dem Problem durch folgende zu ersetzen. Dann kommt aber eine Fehlermeldung.
expFactory.SetValue(Expander.ContentProperty, new ItemsPresenter());
Fehler: 'System.Windows.Controls.ItemsPresenter' is not a valid value for 'FrameworkElementFactory.SetValue'; values derived from Visual or ContentElement are not supported.
Hallo!
Um das ursprüngliche Thema nochmal aufzugreifen: Ich habe das gleiche Problem. Ich will per Code mehrere Gruppierungen mit verschiedenen Hintergrundfarben definierten, die der Anwender selbst auswählt.
var myView = (CollectionView)CollectionViewSource.GetDefaultView(dataGrid.ItemsSource);
if (myView != null) {
myView.GroupDescriptions.Clear();
dataGrid.GroupStyle.Clear();
foreach (var groupDefinition in project.CurrentLayout.GroupingDefinitions) {
if (myView.CanGroup) {
Style style = new Style(typeof(GroupItem));
ControlTemplate template = new ControlTemplate(typeof(GroupItem));
var expFactory = new FrameworkElementFactory(typeof(Expander));
expFactory.SetValue(Expander.IsExpandedProperty, true);
FrameworkElementFactory factoryPresenter = new FrameworkElementFactory(typeof(ItemsPresenter));
expFactory.SetValue(Expander.ContentProperty, factoryPresenter); //<= Problem
template.VisualTree = expFactory;
template.VisualTree.SetValue(Expander.BackgroundProperty, new SolidColorBrush(groupDefinition.Color));
template.VisualTree.SetValue(Expander.ForegroundProperty, Brushes.Black);
template.VisualTree.SetBinding(Expander.HeaderProperty, new Binding(groupDefinition.ToString()));
style.Setters.Add(new Setter(GroupItem.TemplateProperty, template));
var groupStyle = new GroupStyle();
groupStyle.ContainerStyle = style;
groupStyle.Panel = new ItemsPanelTemplate(new FrameworkElementFactory(typeof(DataGridRowsPresenter)));
dataGrid.GroupStyle.Add(groupStyle);
PropertyGroupDescription groupDescription = new PropertyGroupDescription(groupDefinition.ToString());
myView.GroupDescriptions.Add(groupDescription);
}
}
}
Das Gruppieren funktioniert auch im Prinzip. Das Problem ist, dass statt den normalen Zeilen im GridView jetzt nur noch "System.Windows.FrameworkElementFactory" angezeigt wird. Das Problem dabei ist den ItemsPresenter als Content des Expanders zu definieren.
Eine ControlTemplate würde in XAML so aussehen:
<ControlTemplate TargetType="GroupItem">
<Expander IsExpanded="True" Background="White" Foreground="Black" Name="expander">
<Expander.Header>
<TextBlock Text="{Binding Name}" FontWeight="Bold" />
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
Dort kann ich einfach einen ItemsPresenter definieren, im Code ist mir das nicht gelungen.
Ja. Hast recht, die FormCollection habe ich vorher als einziges drin gehabt. Die brauche ich jetzt nicht mehr.
OK. Die serverseitige Validierung funzt. Der Tipp mit dem Controller hat geholfen.
Mir war vorher nicht klar, dass ich der Post-Funktion noch das Modell übergeben muss.
[HttpPost] // v-- das wurde hinzugefügt.
public ActionResult BestellungAbschicken(WarenkorbViewModel viewModel, FormCollection values)
{
...
}
Vielen Dank schon mal für die Antwort. Habe ich gleich ausprobiert.
Leider hat es nicht so funktioniert, wie ich dachte.1.ModelState.IsValid gibt immer true zurück, egal ob ich bei der Checkbox ein Häkchen setze, oder nicht.
1.Die überschriebene Funktion IsValid scheint nicht ausgefüht zu werden. Wenn ich dort einen Haltepunkt setze, passiert dort nichts.
PS: Danke für den Tipp mit den AGB.
Ich bin dabei einen kleinen Webshop mit MVC 3 zu programmieren.
Beim Bestellvorgang werden die Artikel im Warenkorb nochmal angezeigt, damit der Kunde dies Bestätigen kann. Hierfür habe ich ein WarenkorbViewModel angelegt, welches an die View übergeben wird. Da der Kunde die AGBs beim Bestellen akzeptieren muss, habe ich hier ein Bool'sches Feld eingefügt und wollte die Validierung verwenden um zu prüfen, ob das Häkchen gesetzt ist. Da es hierfür anscheinend keine eingebaute Funktion gibt habe ich in Google eine benutzerdefiniertes Validierungsattribut (MustBeTrueAttribute) gefunden, die das machen soll. Leider scheint aber keine Client-Validierung für das Feld zu erfolgen; egal ob ich das Häkchen setze, oder nicht es geht immer weiter.
public class WarenkorbViewModel
{
/// <summary>
/// Dummy-Eigenschaft zum Akzeptieren der AGBs
/// </summary>
[Required]
[MustBeTrue(ErrorMessage = "Sie müssen die AGBs akzeptieren.")]
public bool AkzeptiereAGBs { get; set; }
}
/// <summary>
/// Validation attribute that demands that a boolean value must be true.
/// </summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class MustBeTrueAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
return value != null && value is bool && (bool)value;
}
}
Ich muss mich korrigieren.
Folgende Konstellationen funktionieren:
var query = context.Users.Include("Roles")
.Include("Roles.Rights")
.Where(x => x.UserName == userName);
var query = context.Users.Include("Roles")
.Include("Roles.Modules")
.Where(x => x.UserName == userName);
Hier kommt die beschriebene Fehlermeldung:
var query = context.Users.Include("Roles")
.Include("Roles.Modules")
.Include("Roles.Rights")
.Where(x => x.UserName == userName);
verwendetes Datenbanksystem: MySQL
Hallo!
Kann es sein, dass der MySQL Connector keinen Query Path beim Entity Framework unterstützt?
Hier nochmal genauer:
Das geht:
var query = context.Users.Include("Roles")
.Where(x => x.UserName == userName);
Das nicht:
var query = context.Users.Include("Roles")
.Include("Roles.Rights")
.Where(x => x.UserName == userName);
Fehlermeldung: Methode wird nicht unterstützt.
Hallo!
Gibt es eine Möglichkeit Office-Dokumente, die sich auf dem ASP-Server zum Download befinden direkt im Browser zu öffnen, bearbeiten und wieder hochzuladen, ohne die Datei zwischenzuspeichern? Mir fällt leider nix ein hierzu.
Hallo!
Erst einmal danke für die Antwort.
Ich habe mit den Formatierungseigenschaften etwas rumexperimentiert. Leider ohne erfolg.
Ich habe jetzt ein benutzerdefiniertes DataGridView erstellt, das den Fehler abfängt.
protected override void OnDataError(bool displayErrorDialogIfNoHandler, DataGridViewDataErrorEventArgs e)
{
if (e.Exception is System.ArgumentException && this.Columns[e.ColumnIndex] is NullableDateTimePickerColumn) {
this[e.ColumnIndex, e.RowIndex].Value = null;
e.ThrowException = false;
}
else
base.OnDataError(displayErrorDialogIfNoHandler, e);
}
Ist mit Sicherheit nicht die beste Lösung, funktioniert aber bis jetzt.
Hallo ErfinderDesRades,
das würde wohl schon gehen, ich habe es aber nicht ausprobiert, weil ich die DatenSpalte bereits in ca. 100 DataGridViews einsetze (zur Zeit noch ohne Löschen) und mir eine generische Lösung lieber wäre.
Ich hatte als Workaround das DataError-Event in der Form behandelt. Das ging auch.
Achso.
Man kann bei der ListView Checkboxen anstellen. Die gibt es aber dann nur für das Hauptelement. Ich denke du willst aber eine Checkbox in einer beliebigen Spalte sehen.
Da ist das DataGridView die bessere Wahl.
Wenn es mit einer ListView seien muss, könntest du OwnerDraw auf true stellen, dann musst du dich um das Zeichnen der Elemente selbst kümmern, kannst aber eine Spalte erzeugen, in die du ein Bild einer Checkbox malst. Die muss sich bei einem Klick auf ein Element aber auch aktualisieren. Viel Arbeit!
Tools rein zum Anzeigen der Bilder gibt es wahrscheinlich viele.
Hier ein sehr gutes:
http://code.google.com/p/imagelistview/
Für den Fall dass du das doch selbst machen musst (oder willst) würde ich keine Picturebox nehmen und diese vergrößern, sondern alles "von Hand" zeichnen. Sprich: Nimm ein Panel und überschreib das OnPaint-Ereignis. So hast du viel mehr Kontrolle (und viel mehr Code zu schreiben).
Hallo zusammen,
Ich habe einen DateTime Picker gefunden, der null-Werte unterstützt (Für Datenbankanbindung) und den man auch als NullableDateTimePickerColumn in einer DataGridView verwenden kann.
Damit man nicht nur die eventuellen null-Werte aus der Datenbank anzeigen, sondern auch setzen kann, habe ich das OnKeyUp-Ereignis überschrieben:
protected override void OnKeyUp(KeyEventArgs e)
{
if (e.KeyCode == Keys.Delete || e.KeyCode == Keys.Back)
this.Value = null;
base.OnKeyUp(e);
}
Das funktioniert mit einem normalen NullableDateTimePicker auch, aber eben nicht innerhalb des Datagridviews.
Zum Testen habe ich eine Test-Anwendung angehängt. Zum testen müsst Ihr nur versuchen ein Datum im DGV zu löschen.
Die Fehlermeldung: Das Objekt mit dem Typ "System.DBNull" kann nicht in den Typ "System.Nullable'1[System.DateTime]" konvertiert werden.
Ich setze aber den Wert gar nicht auf DBNull. Ich habe sogar abgefangen, dass die Value-Eigenschaft gar kein DBNull zurückgeben kann.
Da bin ich jetzt schon Wochen dran, ohne wirklich eine Idee zu haben. Wahrscheinlich setzt das DGV intern einen DBNull-Wert. Habe aber keine Ahnung wie ich das Abfangen soll. Jemand eine Idee??
Ohne die Frage verstanden zu haben:
Suchst du vielleicht die CheckedListBox??
Falls du das DGV mit dem Editor erstellt hast, wird für jede Spalte eine Objektinstanz erzeugt und steht als Feld von deiner Form zur Verfügung.
Du kannst also folgendes Schreiben:
dgw.CurrentRow.Cells[column1.Index].Value =
Dein Code über den Spaltennamen sollte aber trotzden funktionieren.
OK. Ich habe das Problem neu eingegrenzt. Ich habe folgende Schritte ausgeführt, um das ganze zu reproduzieren:
WpfControlLibrary1.Window1 w = new WpfControlLibrary1.Window1();
w.Show();
Hier die Code-Behind Datei:
public partial class WindowPhoneList : Window
{
private People employees = null;
public WindowPhoneList()
{
InitializeComponent();
InitWindow();
}
private void InitWindow()
{
System.Drawing.Rectangle Rect = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea;
this.Top = Rect.Bottom - this.Height;
this.Left = Rect.Right - this.Width;
this.WindowState = WindowState.Normal;
this.ShowInTaskbar = false;
this.Visibility = Visibility.Hidden;
}
private class People : ObservableCollection<Employee>
{
public People(List<Employee> employees)
{
foreach (Employee e in employees)
this.Add(e);
}
}
private ICollectionView GetEmployees()
{
if (employees == null) {
CMSManager manager = CMSManager.Instance();
UserRights rights = manager.GetUserRights();
Company c = rights.Company;
employees = new People(manager.GetEmployees(c));
}
return CollectionViewSource.GetDefaultView(employees);
}
#region Window Control
private void Window_Loaded(object sender, RoutedEventArgs e)
{
dataGridEmployees.ItemsSource = GetEmployees();
if (this.WindowState == WindowState.Minimized)
this.WindowState = WindowState.Normal;
}
private void Window_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
{
this.Opacity = 0.9;
}
private void Window_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
{
this.Opacity = 1.0;
}
private void Window_StateChanged(object sender, EventArgs e)
{
this.ShowInTaskbar = !(this.WindowState == WindowState.Minimized);
if (this.WindowState == WindowState.Minimized) {
this.Visibility = Visibility.Hidden;
this.Topmost = false;
}
else {
this.Visibility = Visibility.Visible;
this.Topmost = true;
}
}
#endregion
#region Control Box
private void imageClose_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
{
imageClose.Source = new BitmapImage(new Uri(@"Images/close_hover.png", UriKind.Relative));
DropShadowEffect effect = new DropShadowEffect();
effect.BlurRadius = 20;
effect.ShadowDepth = 3;
effect.Direction = 0;
effect.Color = Colors.Red;
imageClose.Effect = effect;
}
private void imageClose_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
{
imageClose.Source = new BitmapImage(new Uri(@"Images/close.png", UriKind.Relative));
imageClose.Effect = null;
}
private void imageMaximize_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
{
imageMaximize.Source = new BitmapImage(new Uri(@"Images/maximize_hover.png", UriKind.Relative));
DropShadowEffect effect = new DropShadowEffect();
effect.BlurRadius = 20;
effect.ShadowDepth = 3;
effect.Direction = 0;
effect.Color = Colors.Blue;
imageMaximize.Effect = effect;
}
private void imageMaximize_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
{
imageMaximize.Source = new BitmapImage(new Uri(@"Images/maximize.png", UriKind.Relative));
imageMaximize.Effect = null;
}
private void imageMinimize_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
{
imageMinimize.Source = new BitmapImage(new Uri(@"Images/minimize_hover.png", UriKind.Relative));
DropShadowEffect effect = new DropShadowEffect();
effect.BlurRadius = 20;
effect.ShadowDepth = 3;
effect.Direction = 0;
effect.Color = Colors.Blue;
imageMinimize.Effect = effect;
}
private void imageMinimize_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
{
imageMinimize.Source = new BitmapImage(new Uri(@"Images/minimize.png", UriKind.Relative));
imageMinimize.Effect = null;
}
private void imageMaximize_MouseUp(object sender, MouseButtonEventArgs e)
{
if (this.WindowState == WindowState.Maximized)
this.WindowState = WindowState.Normal;
else
this.WindowState = WindowState.Maximized;
}
private void imageClose_MouseUp(object sender, MouseButtonEventArgs e)
{
this.Close();
}
private void imageMinimize_MouseUp(object sender, MouseButtonEventArgs e)
{
this.Visibility = Visibility.Hidden;
}
#endregion
#region Menu Control
private Buttons button = Buttons.BirthdayList;
private void buttonPhoneList_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
SetColumns(Buttons.PhoneList);
}
private void buttonCellPhoneList_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
SetColumns(Buttons.CellPhoneList);
}
private void buttonBirthdayList_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
SetColumns(Buttons.BirthdayList);
}
public void SetColumns(Buttons buttons)
{
this.WindowState = WindowState.Normal;
this.Visibility = Visibility.Visible;
this.button = buttons;
PhoneColumn.Visibility = Visibility.Visible;
CellphoneColumn.Visibility = Visibility.Visible;
EmailColumn.Visibility = Visibility.Visible;
BirthdayColumn.Visibility = Visibility.Visible;
switch (button) {
case Buttons.BirthdayList:
labelHeadline.Content = "Handyliste";
BirthdayColumn.Visibility = Visibility.Collapsed;
CellphoneColumn.Visibility = Visibility.Collapsed;
break;
case Buttons.CellPhoneList:
labelHeadline.Content = "Telefonliste";
BirthdayColumn.Visibility = Visibility.Collapsed;
PhoneColumn.Visibility = Visibility.Collapsed;
break;
case Buttons.PhoneList:
labelHeadline.Content = "Geburtstagsliste";
PhoneColumn.Visibility = Visibility.Collapsed;
CellphoneColumn.Visibility = Visibility.Collapsed;
break;
}
}
#endregion
private void textBoxSearch_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
if (employees == null)
return;
ICollectionView view = GetEmployees();
view.Filter = delegate(object item)
{
return ((Employee)item).ToString().ToLower().Contains(textBoxSearch.Text.ToLower());
};
}
}
Wie beschrieben wird bei einem Tastenanschlag aber gar nicht der Eventhandler textBoxSearch_TextChanged aufgerufen.
Hallo zusammen.
Ich habe ein ganz merkwürdiges Problem im zusammengang mit WPF.
Ich habe ein Fenster mit einem Grid aus dem WPF Toolkit und wollte drüber eine Textbox haben, wo der user Texteingeben kann, nachdem das Grid durchsucht wird.
Ich kann in der Textbox allerdings nichts eintippen. Komischerweise funktioniert Paste und Copy. Ich kann einen Text also einfügen und kann einzelne Buchstaben mit Backspace löschen. Andere Buchstaben gehen nicht.
In anderen Formularen funktioniert die textbox auch wunderbar und ich denke nicht, dass im XAML ein Fehler ist:
<Window x:Class="PhoneList.WindowPhoneList"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="PhoneList" Height="300" Width="687" xmlns:my="http://schemas.microsoft.com/wpf/2008/toolkit" WindowStyle="None" MouseLeave="Window_MouseLeave" MouseEnter="Window_MouseEnter" AllowsTransparency="True" WindowState="Minimized" ShowInTaskbar="False" StateChanged="Window_StateChanged" BorderThickness="0" Opacity="0.9" Visibility="Visible" Background="Black" Loaded="Window_Loaded" Icon="b.ico">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" MinHeight="25" />
<RowDefinition Height="Auto" MinHeight="20" />
<RowDefinition Height="Auto" MinHeight="20" />
<RowDefinition Height="240*" />
</Grid.RowDefinitions>
<ToolBarTray Grid.Row="1" VerticalAlignment="Stretch">
<ToolBarTray.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="DarkGray" Offset="0.0" />
<GradientStop Color="White" Offset="0.25" />
<GradientStop Color="DarkGray" Offset="0.5" />
</LinearGradientBrush>
</ToolBarTray.Background>
<ToolBar Height="Auto" Name="toolBar1" VerticalAlignment="Top" Band="1" BandIndex="1" >
<ToolBar.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="DarkGray" Offset="0.0" />
<GradientStop Color="White" Offset="0.25" />
<GradientStop Color="DarkGray" Offset="0.5" />
</LinearGradientBrush>
</ToolBar.Background>
<Button FocusVisualStyle="{DynamicResource MyFocusVisual}" >
<Image Source="Images/phone_green_32x32.png" Name="buttonPhoneList" MouseLeftButtonDown="buttonPhoneList_MouseLeftButtonDown"></Image>
</Button>
<Button FocusVisualStyle="{DynamicResource MyFocusVisual}" >
<Image Source="Images/phone_red_32x32.png" Name="buttonCellPhoneList" MouseLeftButtonDown="buttonCellPhoneList_MouseLeftButtonDown"></Image>
</Button>
<Button FocusVisualStyle="{DynamicResource MyFocusVisual}" >
<Image Source="Images/phone_blue_32x32.png" Name="buttonBirthdayList" MouseLeftButtonDown="buttonBirthdayList_MouseLeftButtonDown"></Image>
</Button>
</ToolBar>
</ToolBarTray>
<my:DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Path=Employee}" Name="dataGridEmployees" GridLinesVisibility="None" HeadersVisibility="Column" BorderThickness="0" ColumnWidth="Auto" Grid.Row="3">
<my:DataGrid.AlternatingRowBackground>
<SolidColorBrush Color="LightYellow"/>
</my:DataGrid.AlternatingRowBackground>
<my:DataGrid.Columns>
<my:DataGridTextColumn Header="Name" Binding="{Binding Self}" IsReadOnly="True" x:Name="NameColumn" />
<my:DataGridTextColumn Header="Phone" Binding="{Binding Phone}" IsReadOnly="True" x:Name="PhoneColumn" />
<my:DataGridTextColumn Header="Cellphone" Binding="{Binding Cellphone}" IsReadOnly="True" x:Name="CellphoneColumn" />
<my:DataGridHyperlinkColumn Width="Auto" Header="Email" Binding="{Binding Email}" IsReadOnly="True" x:Name="EmailColumn" />
<my:DataGridTextColumn Width="Auto" Header="Birthday" Binding="{Binding Birthday, StringFormat=d}" IsReadOnly="True" x:Name="BirthdayColumn" />
</my:DataGrid.Columns>
</my:DataGrid>
<Grid HorizontalAlignment="Stretch" Margin="0,0,0,0" Name="grid1" Height="25" VerticalAlignment="Top">
<Grid.Background>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="White" Offset="0.0" />
<GradientStop Color="Gray" Offset="0.35" />
<GradientStop Color="Black" Offset="0.4" />
<GradientStop Color="Black" Offset="1.0" />
</LinearGradientBrush>
</Grid.Background>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="27" />
<ColumnDefinition Width="26" />
<ColumnDefinition Width="46" />
<ColumnDefinition Width="5" />
</Grid.ColumnDefinitions>
<Image Name="imageMinimize" Stretch="Fill" Source="Images\minimize.png" Grid.Column="1" MouseEnter="imageMinimize_MouseEnter" MouseLeave="imageMinimize_MouseLeave" Height="18" VerticalAlignment="Top" MouseUp="imageMinimize_MouseUp" HorizontalAlignment="Left" Width="27" />
<Image Grid.ColumnSpan="1" Name="imageMaximize" Stretch="Fill" Source="Images\maximize.png" Grid.Column="2" MouseEnter="imageMaximize_MouseEnter" MouseLeave="imageMaximize_MouseLeave" Height="18" VerticalAlignment="Top" MouseUp="imageMaximize_MouseUp" />
<Image Name="imageClose" Stretch="Fill" Source="Images\close.png" Grid.Column="3" MouseEnter="imageClose_MouseEnter" MouseLeave="imageClose_MouseLeave" Height="18" VerticalAlignment="Top" MouseUp="imageClose_MouseUp" HorizontalAlignment="Right" Width="46" />
</Grid>
<Label Grid.Row="2" Margin="0" Name="labelHeadline" Background="White" VerticalContentAlignment="Center" HorizontalContentAlignment="Left" FontWeight="Bold" FontSize="13" VerticalAlignment="Top" BorderThickness="1" BorderBrush="DarkGray">
Telefonliste
</Label>
<Border Grid.Row="2" CornerRadius="5,5,5,5" Height="24" BorderThickness="1" BorderBrush="Black" Margin="0,2,2,0" VerticalAlignment="Top" HorizontalAlignment="Right" Width="270">
<TextBox BorderThickness="0" Foreground="Black" FontSize="11" VerticalAlignment="Center" Name="textBoxSearch" TextChanged="textBoxSearch_TextChanged">
<TextBox.Background>
<VisualBrush />
</TextBox.Background>
</TextBox>
</Border>
</Grid>
</Window>
Ich habe leider keinen blassen Schimmer an was das liegen könnte. Das Event ist es auf jeden Fall nicth, das wird bei einem Tastenanschlag überhaubt nicht gekastet.
implementiere mal INotifyPropertyChanged
Hatte ich auch schon versucht.
Das liegt daran, dass deine bindable Property die nicht bindable Prop abschattiert (Keyword new). Bennene deine Prop als "Rtf2", und geht.
Das war's nicht.
Hier mein Code. So ging's:
public RichTextBoxEx()
{
base.TextChanged += new EventHandler(RichTextBoxEx_TextChanged);
}
void RichTextBoxEx_TextChanged(object sender, EventArgs e)
{
if (RtfChanged != null)
RtfChanged(this, EventArgs.Empty);
}
public event EventHandler RtfChanged;
[EditorBrowsable(EditorBrowsableState.Advanced), Bindable(true)]
public new string Rtf
{
get
{
return base.Rtf;
}
set
{
if (value != base.Rtf) {
//Just in case new value is text
if (!value.ToLower().StartsWith("{\\rtf"))
base.Text = value;
else
base.Rtf = value;
if (RtfChanged != null)
RtfChanged(this, EventArgs.Empty);
base.Refresh();
}
}
}
Ich würde diesen älteren Beitrag gerne nochmal aufgreifen, da ich zZt. das gleiche Problem habe. Eigentlich sollte es ausreichen, wenn ich folgendes in einer von RichTextBox abgeleiteten Klasse einbaue:
public event EventHandler RtfChanged;
[EditorBrowsable(EditorBrowsableState.Advanced), Bindable(true)]
public new string Rtf
{
get
{
return base.Rtf;
}
set
{
if (value != base.Rtf) {
base.Rtf = value;
if (RtfChanged != null)
RtfChanged(this, EventArgs.Empty);
}
}
}
Es tut aber nicht.
Hallo!
Ich stehe gerade tierisch auf dem Schlauch. Ich verwende Entity Framework und habe ein Objekt mit einer Eigenschaft, die aus der Datenbank gespeist wird und möchte, dass sich eine weitere Eigenschaft mit ändert, falls es Änderungen gibt.
public double? CalculatedProjectAmount
{
get
{
if (ProjectAmount.HasValue && currentCurrency != 0)
return ((double)(this.ProjectAmount.Value)) / currentCurrency;
return null;
}
set
{
if (value == null)
this.ProjectAmount = null;
else {
value = Math.Abs(value.Value);
this.ProjectAmount = (decimal)(value * currentCurrency);
}
}
}
partial void OnProjectAmountChanged()
{
ReportPropertyChanged("CalculatedProjectAmount");
}
Die Eigenschaft ist ProjectAmount und der CalculatedProjectAmount soll sich mit ändern. Eigentlich tut er das auch, aber wenn ich im Frontend eine Textbox an die Eigenschaft ProjectAmount binde kann ich den Wert ändern, aber ich komme nicht mehr aus der Textbox heraus.
Danke schon mal, ich habe das Problem mal im MySQL-Forum gepostet. Ich halte euch auf dem laufenden.
@Icarus666
Sieht mir nach einem peinlichen Bug im SQL Provider für MySQL aus. Kannst du mal das SQL Statement posten das EF an den MySQL Server schickt. (Habe keine Ahnung wie man das bei MySQL abfängt, aber da wird's wohl was geben.) Ich gehe mal davon aus dass dein "Project" Objekt 13 "Contract" Objekte hat und hier ein direkter JOIN statt einem EXISTS verwendet wird.
Hallo!
Sorry, hatte die Antwort verschlafen. Die Abfrage sieht so aus:
SELECT
`Project1`.`C1`,
`Project1`.`anyproblems`,
`Project1`.`awarddatetaskorder`,
`Project1`.`created_at`,
`Project1`.`created_by`,
`Project1`.`datedeleted`,
`Project1`.`deleted`,
`Project1`.`donumber`,
`Project1`.`endawarddate`,
`Project1`.`id`,
`Project1`.`modified_at`,
`Project1`.`modified_by`,
`Project1`.`reasondeleted`,
`Project1`.`safetyproblems`,
`Project1`.`short_description`,
`Project1`.`site`,
`Project1`.`startawarddate`,
`Project1`.`taskorder_comments`,
`Project1`.`taskorder_initialcontractprice`,
`Project1`.`taskorder_internalcomments`,
`Project1`.`taskorder_ntp`,
`Project1`.`taskorder_performancetime`,
`Project1`.`taskorder_projectnumber`,
`Project1`.`taskorder_sitefinaldate`,
`Project1`.`town`,
`Project1`.`userdeleted`,
`Project1`.`address1`,
`Project1`.`address2`,
`Project1`.`street`,
`Project1`.`zip`,
`Project1`.`autocalculatetotal`,
`Project1`.`id1`,
`Project1`.`id2`,
`Project1`.`contract_ID`,
`Project1`.`psp_element`,
`Project1`.`country_id`,
`Project1`.`projectstatus_id`,
`Project1`.`visiblecurrency_id`,
`Project1`.`evaluation_id`,
`Project1`.`id3`
FROM (SELECT
`Extent1`.`address1`,
`Extent1`.`address2`,
`Extent1`.`anyproblems`,
`Extent1`.`autocalculatetotal`,
`Extent1`.`awarddatetaskorder`,
`Extent1`.`contract_ID`,
`Extent1`.`country_id`,
`Extent1`.`created_at`,
`Extent1`.`created_by`,
`Extent1`.`datedeleted`,
`Extent1`.`deleted`,
`Extent1`.`donumber`,
`Extent1`.`endawarddate`,
`Extent1`.`evaluation_id`,
`Extent1`.`id`,
`Extent1`.`modified_at`,
`Extent1`.`modified_by`,
`Extent1`.`projectstatus_id`,
`Extent1`.`psp_element`,
`Extent1`.`reasondeleted`,
`Extent1`.`safetyproblems`,
`Extent1`.`short_description`,
`Extent1`.`site`,
`Extent1`.`startawarddate`,
`Extent1`.`street`,
`Extent1`.`taskorder_comments`,
`Extent1`.`taskorder_initialcontractprice`,
`Extent1`.`taskorder_internalcomments`,
`Extent1`.`taskorder_ntp`,
`Extent1`.`taskorder_performancetime`,
`Extent1`.`taskorder_projectnumber`,
`Extent1`.`taskorder_sitefinaldate`,
`Extent1`.`town`,
`Extent1`.`userdeleted`,
`Extent1`.`visiblecurrency_id`,
`Extent1`.`zip`,
`Extent2`.`id` AS `id1`,
`Extent3`.`id` AS `id2`,
`Extent4`.`id` AS `id3`,
1 AS `C1`
FROM `taskorder` AS `Extent1` LEFT OUTER JOIN `level1` AS `Extent2` ON `Extent1`.`id` = `Extent2`.`projectnumber_id` LEFT OUTER JOIN `leveldefinitions` AS `Extent3` ON (`Extent3`.`projectnumber_id` IS NOT NULL) AND (`Extent1`.`id` = `Extent3`.`projectnumber_id`) LEFT OUTER JOIN `settingsreportlogos` AS `Extent4` ON (`Extent4`.`projectnumber_id` IS NOT NULL) AND (`Extent1`.`id` = `Extent4`.`projectnumber_id`)
WHERE `Extent1`.`contract_ID` = @p__linq__12) AS `Project1`
ORDER BY
`donumber` ASC
Sieht für mich zu kompliziert aus für so eine einfache Abfrage. Die Tabelle taskorder wird übrigens auf das Objekt "Project" gemappt.
Leider habe ich wenig Übung mit verschachtelten SQL-Abfragen. Deswegen nehme ich auch einen ORM 😃
Die Abfrage ergibt direkt auf die Datenbank ausgeführt übrigens auch falsche Resultate. Kommt der fehler deiner Meinung nach vom MySQL-Provider oder vom EF?
Hallo!
Ich habe ein ganz merkwürdiges Verhalten bei Verwendung von MySQL mit dem Entity Framework.
Die folgende Funktion gibt bei mir eine Liste mit 13 identischen Project-Objekten (gleiche ID, gleiche Werte) zurück, obwohl es nur eins geben sollte. Es werden selbst dann 13 Objekte zurückgegeben, wenn ich query.Distinct() hinzufüge.
public List<Project> GetProjects(Contract contract)
{
var query = from i in context.Projects
where i.Contract.ID == contract.ID && i.Deleted == false
orderby i.ProjectNumber
select i;
return query.ToList();
}
Hat jemand ein ähnliches Verhalten festgestellt??
Normalerweise werden in den Service-Pack oder Updates eine DLL verteilt, die die erforderlichen Daten aus verschiedenen Namespaces enthält und diese so erweitert. Die DLLs aus alten Versionen werden meines Wissens nicht überschrieben.
Die Fehlermeldung hat glaube ich was mit dem DB-Provider zu tun. ICh verwende den für MySQL v. 6.0.3
Hatte ich eigentlich auch schon probiert.
Die Fehlermeldung sagt mir allerdings wenig:
Der Typeninitialisierer für System.Data.EntityClient.EntityConnection hat eine Ausnahme verursacht.
System.Data.Common.DbConnectionOptions..ctor(System.String, System.Collections.Hashtable, Boolean)
Auf meinem Entwicklungsrechner funktioniert die Anwendung.
Ich möchte gerne Features aus .NET 3 und 3.5, sprich das Entity Framework und WF in einer Anwendung verwenden.
Aus bestimmten Gründen ist auf den Zielrechnern nur das Framework 2.0 installiert.
Hat jemand Erfahrung damit, ob es funktioniert, wenn ich einfach die referenzierten zum Programm dazulege?
Der einzige Grund, warum man so was brauchen könnte ist für die Datenbindung.
In einem DataGridView mit ComboBox-Spalten gibt es leider keinen ValueMember, wie bei einer normalen ComboBox, an die ich die Objekte direkt binden kann, also muss ich mir hier was anderes überlegen.
Ein anderer Weg ist, dass ich in dem übergeordneten Objekt eine partielle Klasse mit folgendem konstrukt verwenden:
Dazu gab's auch schon einen Thread.
public partial class Company {
public Company Self {
get {
return this;
}
}
}
X(
Mein Fehler natürlich!
Da die Entities eigentlich keine Fremdschlüsselspalten mehr haben hatte ich eine Eigenschaft CompanyID in die partielle Klasse eingefügt, um das zu umgehen. Die Eigenschaft kann ich in LINQ natürlich nicht verwenden.
Folgendes funktioniert hingegen
public List<Employee> GetEmployees(int CompanyId)
{
var emp = from e in context.Employees
orderby e.lastname, e.firstname
where e.Company.id == CompanyId
select e;
...
Hallo!
stehe gerade auf dem Schlauch
bei folgender Linq to Entities-Abfrage kommt die Fehlermeldung
Das angegebene Typelement 'CompanyID' wird in 'LINQ to Entities' nicht unterstützt.
public List<Employee> GetEmployees(int CompanyId)
{
var emp = from e in context.Employees
orderby e.lastname, e.firstname
where e.CompanyID == CompanyId
select e;
...
Hat jemand eine Idee
Ich find's noch nicht mal so schlimm, entspricht jedenfalls eher der Objektorientierung, als zusätzlich eine company_id-Eigenschaft mitzuverwalten.
BTW: Bei einer "normalen" ComboBox kannst du auch den ValueMember für die Company-Klasse verwenden, dann braucht man das Self nicht. Hier ging es um die DataGridViewComboBoxColumns.
Problem gelöst:
Ich musste nur für die Klasse (bei mir Company), die ich in der DataGridViewComboBox als Auswahl haben will 2 Eigenschaften erstellen, an die ich binden kann:
public partial class Company
{
public string Name
{
get
{
return companyname;
}
}
public Company Self
{
get
{
return this;
}
}
}
Spalte im DGV initialisieren:
ObjectQuery<Company> companyQuery = ctx.Companies;
CompanyColumn.DataPropertyName = "Company";
CompanyColumn.DataSource = companyQuery;
CompanyColumn.ValueMember = "Self";
CompanyColumn.DisplayMember = "Name";