使用数据绑定更改 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.

进行双向绑定。有两种情况:

  1. 如果您只想反映对 Name 和 Enabled 等属性的更改。只需进行以下更改:

    <CheckBox IsChecked="{Binding Enabled, Mode=TwoWay}"/>
    <TextBox Grid.Column="1" Text="{Binding Name, Mode=TwoWay}"/>
    
  2. 如果您想像 add/delete 操作一样反映到集合中,请使用自定义绑定到项目源 属性,如下所示:

    Binding sbinding = new Binding();
    sbinding.Source = App.screens;
    sbinding.Mode = BindingMode.TwoWay;
    screenListBox.SetBinding(ItemsControl.ItemsSourceProperty, sbinding);
    

我已经测试了你的方案,效果很好。