【问题标题】:Binding List of Items in WPFWPF中的项目绑定列表
【发布时间】:2017-07-30 12:57:04
【问题描述】:

我尝试实现 MVVM。 View 中的 TextBox 文本绑定到 Model 中的属性 itemName。

视图上是 DataGrid -> 绑定到 ViewModel.Rows 属性

在 ViewModel 上的 itemName on change 事件运行异步请求到远程服务的产品,这将转到模型 SugestProducts 属性。 SugestProducts 属性是 ListView 项目的来源。

如果产品超过 0 个列表视图打开。 ListView SelectedItem 绑定到模型产品属性。

我需要在列表视图中选择产品,从 Product.name 属性中填充 itemName 属性,而无需请求远程服务。其他工作不错。

我的模型是:

public class RowDocumentSaleWraper : INotifyPropertyChanged
{
    private ObservableCollection<Product> _sugestProducts;
    public ObservableCollection<Product> SugestProducts 
    { 
        get
        {
            return _sugestProducts;
        }
        set
        {
            _sugestProducts = value;
            NotifyPropertyChanged("SugestProducts");
        }
    }

        public Product product {get; set;}
         _itemName
        public override string itemName
        {
            get
            {
                return itemName;
            }
            set
            {
                itemName = value;
                NotifyPropertyChanged("itemName");
            }
        }  
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
}

产品:

public class Product
{
    public string name{get; set;}
}

我的 ViewModel 是:

public class OrderViewModel : DependencyObject
{
       public ObservableCollection<RowDocumentSaleWraper> Rows { get; set; }

    public OrderViewModel()
    {
        addNewRow();
    }
        internal void addNewRow()
        {
            RowDocumentSaleWraper row = new RowDocumentSaleWraper(Order);
            row.PropertyChanged += row_PropertyChanged;
            Rows.Add(row);
        }
    void row_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        RowDocumentSaleWraper row = sender as RowDocumentSaleWraper;

        if (row != null && e.PropertyName == "itemName" && !String.IsNullOrEmpty(row.itemName))
        {
            //get products from remote service -> source for 
            requestProducts(row.itemName, row);
        }
    }
    private async void requestProducts(string searchString, RowDocumentSaleWraper row)
    {
        if (!String.IsNullOrEmpty(searchString))
        {
            var products = await requestProductsAsync(searchString);

            row.SugestProducts = listToObservable(products);
        }

    }
}

我的 Xaml:

<DataGrid Grid.Row="1" Name="mainDataGrid" ItemsSource="{Binding Rows , UpdateSourceTrigger=PropertyChanged}" AutoGenerateColumns="False" CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Product">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Vertical">
                                <TextBox PreviewKeyDown="TextBox_PreviewKeyDown" KeyDown="TextBox_KeyDown" Text="{Binding itemName, UpdateSourceTrigger=PropertyChanged}" MinWidth="200"/>
                                <ListView ItemsSource="{Binding SugestProducts, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"  
                                          KeyDown="ListView_KeyDown" SelectedItem ="{Binding product, UpdateSourceTrigger=PropertyChanged}">
                                    <ListView.View>
                                        <GridView ColumnHeaderContainerStyle="{StaticResource myHeaderStyle}">
                                            <GridViewColumn  DisplayMemberBinding="{Binding code}"/>
                                            <GridViewColumn  DisplayMemberBinding="{Binding name}" />
                                        </GridView>
                                    </ListView.View>
                                </ListView>
                            </StackPanel>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>

【问题讨论】:

  • 1) 您根本不需要在 ViewModel 中使用 DependencyPropertyObservableCollection 就足够了 2) INotifyPropertyChanged 的实现对于您的模型和视图模型类是相同的跨度>
  • 问题如果将 product.name 放置到 RowDocumentSaleWraper.itemName 它从远程服务开始请求,在它重写 listview 项目的源并将 RowDocumentSaleWraper.product 第二次设置为 null 之后
  • 再次,从合理的基本代码开始,然后继续进行更高级的变体和问题
  • 好的。我更改了代码。但我有同样的问题
  • public class OrderViewModel : DependencyObject => 这是错误的......和 ​​c.tor 中的row.PropertyChanged += row_PropertyChanged;,再次没有任何意义

标签: c# wpf mvvm binding


【解决方案1】:

基于上面的cmets,你应该从itemName的setter通知ViewModel

    public override string itemName
    {
        get
        {
            return itemName;
        }
        set
        {
            itemName = value;
            NotifyPropertyChanged("itemName");
            NotifyChange(itemName); 
        }
    } 

然后您将定义事件以检索数据

private async void NotifyChange(string name)
{
    if (!String.IsNullOrEmpty(searchString))
    {
        var products = await requestProductsAsync(searchString);

        SugestProducts = listToObservable(products);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-08
    • 1970-01-01
    • 1970-01-01
    • 2021-04-16
    • 1970-01-01
    相关资源
    最近更新 更多