UWP, как обновить привязанный TextBox с изменениями в выбранном элементе связанного ListView - PullRequest
0 голосов
/ 09 марта 2019

У меня есть страница 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.

Я не знаю, как поступить, любая помощь будет признательна.

1 Ответ

0 голосов
/ 11 марта 2019

Режим 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;
    }
}
...