Ich habe eine Listenansicht, in der jede Zeile 5 Einträge enthält. Das Listenfeld sieht wie folgt aus:C# Anzeige des Textfelds (in der Listenansicht) Wert in einem Meldungsfeld (wpf)
Ich brauche (Display) zu speichern, den Namen der Variablen und den Wert in „Physical Wert“ Spalte Textfeld, wenn ich OK-Taste drücken. Für z.B. Wenn ich 45 in das Textfeld für den physikalischen Wert eingebe (nur eine Zeile gleichzeitig), sollte der Name der Variablen und der Wert "45" gespeichert (angezeigt) werden. Ich bin in der Lage, den Namen der Variablen, aber nicht den Wert des Textfelds abzurufen.
Mein Versuch:
Dieser Code wird die Listenansicht mit Variablen füllen und an die Eigenschaften binden.
public void Populatevariables(IList<string> variables)
{
int rowcount = 0;
dataGrid.RowDefinitions.Clear();
dataGrid.ColumnDefinitions.Clear();
RowDefinition rd = new RowDefinition();
rd.Height = new GridLength();
dataGrid.RowDefinitions.Add(rd);
dataGrid.RowDefinitions.Add(new RowDefinition());
dataGrid.ColumnDefinitions.Add(new ColumnDefinition());
Label t1 = new Label();
t1.Content = "Variables";
Grid.SetColumn(t1, 0);
Grid.SetRow(t1, rowcount);
dataGrid.Children.Add(t1);
ListView VrblPopulateList = new ListView();
GridView g1 = new GridView();
g1.AllowsColumnReorder = true;
//l1.View = g1;
GridViewColumn g2 = new GridViewColumn();
g2.Header = "Name";
g2.Width = 200;
g2.DisplayMemberBinding = new Binding("Name");
g1.Columns.Add(g2);
GridViewColumn g5 = new GridViewColumn();
g5.Header = "DataType";
g5.Width = 200;
g5.DisplayMemberBinding = new Binding("DataType");
g1.Columns.Add(g5);
GridViewColumn g3 = new GridViewColumn();
g3.Header = "Current Value";
g3.Width = 200;
DataTemplate dt1 = new DataTemplate();
FrameworkElementFactory FF1 = new FrameworkElementFactory(typeof(TextBox));
FF1.SetBinding(TextBox.BindingGroupProperty, new Binding("Current_Value"));
FF1.SetValue(FrameworkElement.HeightProperty, Height = 30);
FF1.SetValue(FrameworkElement.WidthProperty, Width = 150);
dt1.VisualTree = FF1;
g3.CellTemplate = dt1;
g1.Columns.Add(g3);
GridViewColumn g6 = new GridViewColumn();
g6.Header = "Physical Value";
g6.Width = 200;
DataTemplate dt2 = new DataTemplate();
FrameworkElementFactory FF2 = new FrameworkElementFactory(typeof(TextBox));
FF2.SetBinding(TextBox.BindingGroupProperty, new Binding("Physical_Value"));
//FF2.AddHandler(TextBox.TextChangedEvent, txtchanged, true);
FF2.SetValue(FrameworkElement.HeightProperty, Height = 30);
FF2.SetValue(FrameworkElement.WidthProperty, Width = 150);
dt2.VisualTree = FF2;
g6.CellTemplate = dt2;
g1.Columns.Add(g6);
GridViewColumn g4 = new GridViewColumn();
g4.Header = "Action";
g4.Width = 200;
DataTemplate dt = new DataTemplate();
FrameworkElementFactory FF = new FrameworkElementFactory(typeof(Button));
FF.SetBinding(Button.BindingGroupProperty, new Binding("ToDo"));
FF.SetValue(FrameworkElement.HeightProperty,Height = 30);
FF.SetValue(FrameworkElement.WidthProperty, Width = 150);
FF.SetValue(System.Windows.Controls.Button.ContentProperty,"OK");
FF.AddHandler(Button.ClickEvent, new RoutedEventHandler(b1_click));
dt.VisualTree = FF;
g4.CellTemplate = dt;
g1.Columns.Add(g4);
VrblPopulateList.View = g1;
Grid.SetRow(VrblPopulateList, rowcount + 1);
dataGrid.Children.Add(VrblPopulateList);
for (int i = 0; i < variables.Count; i++)
{
Label lb1 = new Label();
lb1.Content = variables[i].Name;
Label lb2 = new Label();
lb2.Name = variables[i].datatype;
DataTemplate dd = new DataTemplate();
TextBox tb = new TextBox();
tb.Name = "TextBox" + i.ToString();
Button b1 = new Button();
VrblPopulateList.Items.Add(new User() { Name = lb1.Content, DataType = lb2.Name, Current_Value = tb, Physical_Value = tb, ToDo = b1 });
}
}
Dieser Code definiert die Eigenschaft, die binden, während bevölkern:
public class User
{
public object Name { get; set; }
public string DataType { get; set; }
public Control Current_Value
{
get;
set;
}
public Control Physical_Value
{
get;
set;
}
public Control ToDo { get; set; }
}
Endlich wird dieser Code alle Elemente abrufen, wenn Schaltfläche geklickt wird.
private void b1_click(object sender, RoutedEventArgs e)
{
User item = (User)((Button)sender).DataContext;
TextBox t = (TextBox)item.Physical_Value;
MessageBox.Show(item.Name.ToString() + t.Text);
}
Der Textfeldwert ist immer leer. Ich weiß, dass es gelöst werden kann, indem der Handler während des Auffüllens zum "Text geändert" -Ereignis hinzugefügt wird. Aber ich weiß nicht, wie es geht. Bitte helfen Sie.
Haben Sie versucht, die 'UpdateSourceTrigger'-Eigenschaft der Bindung auf 'PropertyChanged' zu setzen und Ihr Benutzermodell zu ändern, anstatt die Physical_Value-Eigenschaft von Control, sondern als Zeichenfolge (die Sie an die Text-Eigenschaft des Textfelds in der Datatemplate gebunden haben) ? –
Meinst du das? FF2.SetBinding (TextBox.BindingGroupProperty, neue Bindung ("Physical_Value") {UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged}); – sats
Ja, aber Sie sollten auch Ihr Modell ändern. Ihr Modell sollte keine Steuerelemente enthalten. Es sollte Werte enthalten, die Steuerelemente in Ihrem XAML verwenden müssen. Ich würde vorschlagen, dass Sie etwas in diesem Artikel tun würden (http://www.wpf-tutorial.com/datagrid-control/custom-columns/). Dies würde Ihren Code so viel lesbarer machen. –