如何在DataGrid中绑定两个依赖的ComboBox

时间:2013-06-24 12:27:26

标签: c# wpf xaml datagrid datagridcomboboxcolumn

我的WPF数据网格有问题。我有两个ComboBox列,第二个应该设置它的datacontext取决于第一个中选择的内容。

视图模型

public class MyCollection: AbstractViewModel
{
    private BindingList<string> _subitems;
    public BindingList<string> Subitems
    {
        get { return _subitems; }
        set { _subitems = value; Notify("Subitems");}
    }

    private string _name;
    public string Name
    {
        get { return _name; }
        set { _name = value; Notify("Name");}
    }
}

的Xaml

<DataGridTemplateColumn>
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding SelectedName}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <ComboBox SelectedValuePath="Name"
                      x:Name="CollectionBox"
                      SelectedValue="{Binding SelectedName}"
                      DisplayMemberPath="Name"
                      ItemsSource="{Binding SomeBinding}"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn >
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding SelectedSubitem}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <ComboBox SelectedValue="{Binding SelectedSubitem}"
                      ItemsSource="{Binding ElementName=CollectionBox, Path=SelectedItem.Subitems}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

我的第一个ComboBox的绑定没问题,但我在第二个ComboBox中没有看到任何项目(viewmodel有ComboBoxes的booth的条目);只有TextBox绑定按预期工作。我也尝试使用ComboBoxColumn但结果相同。

2 个答案:

答案 0 :(得分:2)

这是一个简单的工作示例,您可以如何使用ViewModel来满足您的需求

<强> XAML

   <DataGrid ItemsSource="{Binding Source}" Width="500">
        <DataGrid.Columns>
        <DataGridTemplateColumn Header="main" Width="100">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding SelectedName}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <ComboBox SelectedValuePath="Name"                      
                                  SelectedValue="{Binding SelectedName}"                                  
                                  SelectedItem="{Binding SelectedMainItem, UpdateSourceTrigger=PropertyChanged}"                      
                                  DisplayMemberPath="Name"                      
                                  ItemsSource="{Binding SomeBinding}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>
            <DataGridTemplateColumn Header="sub" Width="100">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding SelectedSubitem}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <ComboBox SelectedValue="{Binding SelectedSubitem}"                      
                                  ItemsSource="{Binding  Path=SelectedMainItem.Subitems}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>

背后的代码

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new VMColl();
    }
}

public class VMColl
{
    List<VM> source;

    public List<VM> Source
    {
        get { return source; }
        set { source = value; }
    }

    public VMColl()
    {
        source  = new List<VM>(){new VM(),new VM(),new VM(),new VM()};
    }
}

/// <summary>
/// your Row
/// </summary>
public class VM : Notify
{
    private List<mainObj> _items;
    public List<mainObj> SomeBinding
    {
        get { return _items; }
        set
        {
            _items = value;
            OnPropertyChanged("Items");
        }
    }

    private string _selectedName;
    public string SelectedName
    {
        get { return _selectedName; }
        set
        {
            _selectedName = value;
            OnPropertyChanged("SelectedName");
        }
    }

    private mainObj _selectedMainItem;
    public mainObj SelectedMainItem
    {
        get { return _selectedMainItem; }
        set
        {
            _selectedMainItem = value;
            OnPropertyChanged("SelectedMainItem");
            OnPropertyChanged("SelectedMainItem.Subitems");
        }
    }

    private string _selectedSubitem;
    public string SelectedSubitem
    {
        get { return _selectedSubitem; }
        set
        {
            _selectedSubitem = value;
            OnPropertyChanged("SelectedSubitem");
        }
    }

    public VM()
    {
        SomeBinding = new List<mainObj>() {new mainObj("first"),new mainObj("second"),new mainObj("someother") };
    }
}

public class mainObj : Notify
{
    private BindingList<string> _subitems;
    public BindingList<string> Subitems
    {
        get { return _subitems; }
        set
        {
            _subitems = value;
            OnPropertyChanged("Subitems");
        }
    }

    private string _name;
    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            OnPropertyChanged("Name");
        }
    }

    public mainObj(string name)
    {
        _name = name;
        _subitems = new BindingList<string>(){"1","2","3"};
    }
}

public class Notify : INotifyPropertyChanged
{
    // Declare the event 
    public event PropertyChangedEventHandler PropertyChanged;

    // Create the OnPropertyChanged method to raise the event 
    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
}

答案 1 :(得分:0)

@WiiMaxx答案的更新

要获取选定子项目的值,您必须在第二个组合框中添加一个触发器:

 <DataTemplate>
         <ComboBox SelectedValue="{Binding SelectedSubitem , UpdateSourceTrigger=PropertyChanged}"                      
                       ItemsSource="{Binding  Path=SelectedMainItem.Subitems}" />
 </DataTemplate>