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