使用数据绑定更改 UI 中的数据
Change data from UI with data binding
我对Windows10编程中数据绑定的理解是GUI可以反映数据的变化,也可以操作数据。我错了吗?
我有在应用程序中定义的自定义数据列表。
public static ObservableCollection<Screen> screens;
Screen的结构是这样的
public class Screen : INotifyPropertyChanged
{
private string name;
public string Name
{
get { return this.name; }
set
{
if (this.name != value)
{
this.name = value;
this.NotifyPropertyChange("Name")
}
}
}
public bool Enabled { /* same as Name*/ }
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propName)
{
if (this.PropertyChanged != null)
{
this.PropertyChange(this, new PropertyChangeEventArgs(propName));
}
}
}
在我的一个页面中,比方说第 1 页,我在 xaml
中定义了一个列表框
<ListBox Name="screenListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100">
<ColumnDefinition Width="*">
</Grid.ColumnDefinitions>
<CheckBox IsChecked="{Binding Enabled}">
<TextBox Grid.Column="1" Text="{Binding Name}">
<DataTemplate>
<ListBox.ItemTemplate>
</ListBox>
然后我将列表框绑定到 App 中的屏幕列表
screenListBox.ItemsSource = App.screens
在page1的构造函数中,我实例化了2个屏幕
App.screens = new ObservableCollection<Screen>() { /*some initial list*/ };
还有另一个页面,比方说 page2,单击一个按钮从 page1 导航到 page2,因为屏幕在 App 中并且 public 是静态的。所以在第 2 页我可以访问它们。
this.Frame.Navigate(typeof(Page2), null);
问题是在我通过第 1 页上的 GUI 进行一些更改后,它们没有反映回 App 中的屏幕列表。一个例子是,如果我更改了 page1 列表中第一项的名称,然后在页面切换之前设置了一个断点,我可以看到屏幕列表没有改变。我还尝试使用复选框点击处理程序并手动更新 isEnable 属性。但是我在列表中好像找不到checkbox对应的索引。
如有任何帮助,我们将不胜感激!谢谢。
编辑: 使屏幕继承自 INotifyPropertyChanged。
编辑: 使用 ObservableCollection 而不是 List
编辑:无法在其事件处理程序中找出点击的复选框的索引
我认为所有其他人的建议都有帮助。 @Justin XL 指出了如何让它反映到后端 object/collection.
进行双向绑定。有两种情况:
如果您只想反映对 Name 和 Enabled 等属性的更改。只需进行以下更改:
<CheckBox IsChecked="{Binding Enabled, Mode=TwoWay}"/>
<TextBox Grid.Column="1" Text="{Binding Name, Mode=TwoWay}"/>
如果您想像 add/delete 操作一样反映到集合中,请使用自定义绑定到项目源 属性,如下所示:
Binding sbinding = new Binding();
sbinding.Source = App.screens;
sbinding.Mode = BindingMode.TwoWay;
screenListBox.SetBinding(ItemsControl.ItemsSourceProperty, sbinding);
我已经测试了你的方案,效果很好。
我对Windows10编程中数据绑定的理解是GUI可以反映数据的变化,也可以操作数据。我错了吗?
我有在应用程序中定义的自定义数据列表。
public static ObservableCollection<Screen> screens;
Screen的结构是这样的
public class Screen : INotifyPropertyChanged
{
private string name;
public string Name
{
get { return this.name; }
set
{
if (this.name != value)
{
this.name = value;
this.NotifyPropertyChange("Name")
}
}
}
public bool Enabled { /* same as Name*/ }
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propName)
{
if (this.PropertyChanged != null)
{
this.PropertyChange(this, new PropertyChangeEventArgs(propName));
}
}
}
在我的一个页面中,比方说第 1 页,我在 xaml
中定义了一个列表框<ListBox Name="screenListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100">
<ColumnDefinition Width="*">
</Grid.ColumnDefinitions>
<CheckBox IsChecked="{Binding Enabled}">
<TextBox Grid.Column="1" Text="{Binding Name}">
<DataTemplate>
<ListBox.ItemTemplate>
</ListBox>
然后我将列表框绑定到 App 中的屏幕列表
screenListBox.ItemsSource = App.screens
在page1的构造函数中,我实例化了2个屏幕
App.screens = new ObservableCollection<Screen>() { /*some initial list*/ };
还有另一个页面,比方说 page2,单击一个按钮从 page1 导航到 page2,因为屏幕在 App 中并且 public 是静态的。所以在第 2 页我可以访问它们。
this.Frame.Navigate(typeof(Page2), null);
问题是在我通过第 1 页上的 GUI 进行一些更改后,它们没有反映回 App 中的屏幕列表。一个例子是,如果我更改了 page1 列表中第一项的名称,然后在页面切换之前设置了一个断点,我可以看到屏幕列表没有改变。我还尝试使用复选框点击处理程序并手动更新 isEnable 属性。但是我在列表中好像找不到checkbox对应的索引。
如有任何帮助,我们将不胜感激!谢谢。
编辑: 使屏幕继承自 INotifyPropertyChanged。
编辑: 使用 ObservableCollection 而不是 List
编辑:无法在其事件处理程序中找出点击的复选框的索引
我认为所有其他人的建议都有帮助。 @Justin XL 指出了如何让它反映到后端 object/collection.
进行双向绑定。有两种情况:
如果您只想反映对 Name 和 Enabled 等属性的更改。只需进行以下更改:
<CheckBox IsChecked="{Binding Enabled, Mode=TwoWay}"/> <TextBox Grid.Column="1" Text="{Binding Name, Mode=TwoWay}"/>
如果您想像 add/delete 操作一样反映到集合中,请使用自定义绑定到项目源 属性,如下所示:
Binding sbinding = new Binding(); sbinding.Source = App.screens; sbinding.Mode = BindingMode.TwoWay; screenListBox.SetBinding(ItemsControl.ItemsSourceProperty, sbinding);
我已经测试了你的方案,效果很好。