我的应用:商店有一个Products集合和一个int Id属性。 Product具有字符串ProductCode和Description属性。 ViewModel引用Store的单个实例。 ViewModel有一个静态的Products(ProductList)集合。 My View的DataContext设置为ViewModel。我的视图通过ViewModel显示Store。
什么有效:我的视图有一个TextBlock绑定到商店的ID。
什么不起作用:My View有一个DataGrid,用于将商品添加到商店的产品系列。用于将商品添加到商店产品系列的DataGrid允许我使用DataGridComboBoxColumn列选择新的ProductCode。这很好用。但是,我希望我选择的ProductCode更新绑定到Product's Description的DataGridTextBoxColumn。
我花了好几个小时搜索网络,但我找不到任何与我的情景完全匹配的内容,除了"示例12"从这个链接,但我还没有得到它为我的项目工作:Best ComboBox Tutorial Ever
我的观点中的代码段:
<StackPanel>
<TextBlock Text="{Binding Store.Id}"/>
<DataGrid ItemsSource="{Binding Store.Products}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridComboBoxColumn
Header="ProductCode"
ItemsSource="{x:Static m:ItemsProvider.ProductList}"
SelectedValueBinding="{Binding ProductCode, UpdateSourceTrigger=PropertyChanged}"
SelectedValuePath="ProductCode"
DisplayMemberPath="ProductCode"/>
<!--
I want Description for my chosen Product to pop in automatically... but how?
-->
<DataGridTextColumn Header="Description" Binding="{Binding Description}"/>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
我的ViewModel:
public class ViewModel : NotifyObject
{
// Constructor
public ViewModel()
{
_store = new Store() { Id = 1 };
}
// Fields
Store _store;
Product _selectedProduct;
// Properties
public Store Store {
get { return _store; }
set {
_store = value;
base.NotifyPropertyChanged("Commission");
}
}
}
我的产品型号:
public class Product : NotifyObject
{
// Constructor
public Product() { }
// Fields
string _productCode;
string _description;
// Properties
public string ProductCode {
get { return _productCode; }
set {
_productCode = value;
base.NotifyPropertyChanged("ProductCode");
RefreshDescription(ProductCode);
}
}
public string Description {
get { return _description; }
set {
_description = value;
base.NotifyPropertyChanged("Description");
}
}
// Private Methods
void RefreshDescription(string productCode)
{
if (ItemsProvider.ProductList.Count == 0) {
return;
}
Product product = ItemsProvider.ProductList.FirstOrDefault(p => p.ProductCode == productCode);
this.Description = (product == null ? "" : product.Description);
}
}
我的商店型号:
public class Store : NotifyObject
{
// Constructor
public Store()
{
Products = new ObservableCollection<Product>();
}
// Fields
int _id;
// Properties
public int Id {
get { return _id; }
set {
_id = value;
base.NotifyPropertyChanged("Id");
}
}
public ObservableCollection<Product> Products { get; set; }
}
我的静态类,用于获取可供选择的产品列表:
public static class ItemsProvider
{
static ObservableCollection<Product> _productList = new ObservableCollection<Product>();
static ItemsProvider()
{
_productList = new ObservableCollection<Product>() {
new Product() { ProductCode = "111", Description = "a" },
new Product() { ProductCode = "222", Description = "b" },
new Product() { ProductCode = "333", Description = "c" },
new Product() { ProductCode = "444", Description = "d" }
};
}
public static ObservableCollection<Product> ProductList {
get {
return _productList;
}
}
}
答案 0 :(得分:2)
执行此操作的一种简单方法是在产品代码更改时引发PropertyChanged
,然后执行查找以获取说明:
// Properties
public string ProductCode {
get { return _productCode; }
set {
_productCode = value;
base.NotifyPropertyChanged("ProductCode");
base.NotifyPropertyChanged("Description");
}
}
public string Description {
get {
var matchingProduct = ViewModel.ProductList.FirstOrDefault(product => product.ProductCode == ProductCode);
return (matchingProduct == null ? "" : matchingProduct.Description);
}
}
对于上述内容,更好的方法可能是为ProductList和Products集合定义不同的类。前者应该是 ProductType (包含产品代码和描述),后者应该是 ProductInstance (仅包含产品代码)。然后你可以使用类似上面的内容来定义后一类的只读产品描述。
答案 1 :(得分:1)
来自我编辑过的问题:
对我的代码进行的最重要的更改是在为Product设置ProductCode之后触发的RefreshDescription方法。此方法将ProductCode作为参数,并查询静态ProductList以查找第一个匹配的Description。如果需要,用户可以更改自动填充的Description属性。
再次感谢那些帮助我得出这个结论的人!