更改ComboBox值时更新TextBox文本

时间:2014-08-27 20:28:32

标签: c# wpf wpfdatagrid

我的应用:商店有一个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

解决:

对我的代码进行的最重要的更改是在为Product设置ProductCode之后触发的RefreshDescription方法。此方法将ProductCode作为参数,并查询静态ProductList以查找第一个匹配的Description。如果需要,用户可以更改自动填充的Description属性。

我的观点中的代码段:

<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;
        }           
    }           
}

2 个答案:

答案 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属性。

再次感谢那些帮助我得出这个结论的人!