首页 > 解决方案 > UWP如何使用绑定ListView的选定项中的更改来更新绑定的TextBox

问题描述

我有一个 UWP 页面,其中包含一个带有文本框和一个 ListView 控件的表单。ListView 控件绑定到产品集合。我希望绑定的文本框应该显示有关列表视图中选择的产品的信息。

public class Product: INotifyPropertyChanged
    {
        public int ProductID { get; set; }

        private string name;
        public string Name {
            get { return name; }
            set
            {
                if (name==value)
                    return;
                name = value;
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(nameof(Name)));
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        public Product(int pid, string name)
        {
            ProductID = pid;
            Name = name;
        }
    }
}

XAML 如下:

    <TextBox x:Name="txtProductId" Grid.Row="1" Grid.Column="1" 
             Text="{x:Bind CurrentProduct.ProductID}"/>

    <TextBox x:Name="txtProductName" Grid.Row="2" Grid.Column="1" 
             Text="{x:Bind CurrentProduct.Name}" />

    <ListView x:Name="lstProducts" Grid.Row="3" Grid.ColumnSpan="2"
              ItemsSource="{x:Bind ProductList}"
              SelectedItem="{x:Bind CurrentProduct, Mode=TwoWay}"
              ItemTemplate="{StaticResource lstDataTemplate}"
              >
    </ListView>

以下代码在 Page_Loaded 上执行:

CurrentProduct = Products[0];
DataContext = CurrentProduct;

ListView 绑定到 ProductList(类型 ObservableCollection)。我注意到通过在单步模式下执行应用程序,CurrentProduct 的值正在发生变化,但我认为由于它是引用而不是 DataContext 的属性发生变化,因此永远不会触发 PropertyChanged 事件并且 TextBox 不会更新以显示 CurrentProduct 的名称。

我不知道如何继续,任何帮助将不胜感激。

标签: data-bindinguwp

解决方案


X:Bind默认模式是,在您的OneTime情况下,您需要将模式设置为OneWay

我做了一个代码示例供您参考:

<TextBox x:Name="txtProductId" Grid.Row="1" Grid.Column="1" 
         Text="{x:Bind CurrentProduct.ProductID,Mode=OneWay}"/>

<TextBox x:Name="txtProductName" Grid.Row="2" Grid.Column="1" 
         Text="{x:Bind CurrentProduct.Name,Mode=OneWay}" />

<ListView x:Name="lstProducts" Grid.Row="3" Grid.ColumnSpan="2"
          ItemsSource="{x:Bind ProductList}"
          SelectedItem="{x:Bind CurrentProduct, Mode=TwoWay}"
          >
</ListView>
public sealed partial class MainPage : Page, INotifyPropertyChanged
{
    public MainPage()
    {
        this.InitializeComponent();
        this.Loaded += MainPage_Loaded;
    }
    private void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        for (int i = 0; i < 10; i++)
        {
            ProductList.Add(new Product(i, "name " + i));
        }
    }

    public ObservableCollection<Product> ProductList { get; set; } = new ObservableCollection<Product>();

    private Product _CurrentProduct = new Product(100,"test");

    public event PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged(string PropertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this,new PropertyChangedEventArgs(PropertyName));
        }
    }
    public Product CurrentProduct
    {
        get { return _CurrentProduct; }
        set
        {
            if (_CurrentProduct != value)
            {
                _CurrentProduct = value;
                RaisePropertyChanged("CurrentProduct");
            }
        }
    }
}
public class Product : INotifyPropertyChanged
{
    public int ProductID { get; set; }

    private string name;
    public string Name
    {
        get { return name; }
        set
        {
            if (name == value)
                return;
            name = value;
            RaisePropertyChanged("Name");
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged(string PropertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
        }
    }
    public Product(int pid, string name)
    {
        ProductID = pid;
        Name = name;
    }

    public override string ToString()
    {
        return Name;
    }
}

推荐阅读