尝试将嵌套属性模型绑定到DataGrid

时间:2013-11-30 20:45:11

标签: c# wpf xaml datagrid

我的DataGrid包含2列ComboBox。简单的方法是使用List<string>,但由于我需要额外的功能(能够动态禁用某些下拉菜单项),我的代码后面使用嵌套属性:DataGrid的顶级和更低级别的ComboBox。

请参阅下面的相关代码(在不同的尝试和变体中):

左栏XAML:

<DataGridTemplateColumn Header=" Left Column ">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <ComboBox ItemsSource="{Binding SteelThickness, RelativeSource={RelativeSource AncestorType=Window}}" SelectedItem="{Binding LeftValues, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" SelectionChanged="ComboBox_SelectionChanged" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

右栏XAML:

<DataGridTemplateColumn Header=" Right Column ">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <ComboBox ItemsSource="{Binding Caliber, RelativeSource={RelativeSource AncestorType=Window}, Mode=TwoWay}" DisplayMemberPath="Thickness" SelectedItem="{Binding Thickness, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" SelectionChanged="ComboBox_SelectionChanged">
                <ComboBox.ItemContainerStyle>
                    <Style TargetType="{x:Type ComboBoxItem}">
                        <Setter Property="IsEnabled" Value="{Binding Enabled}"/>
                    </Style>
                </ComboBox.ItemContainerStyle>
            </ComboBox>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

GridModel.cs:

public class GridModel : PropertyChangedBase
{
    public int Item { get; set; }

    private string _LeftValues;
    public string LeftValues
    {
        get
        {
            return _LeftValues;
        }
        set
        {
            if (_LeftValues != value)
            {
                _LeftValues = value;
                RaisePropertyChanged("LeftValues");
            }
        }
    }

    private string _RightValues;
    public string RightValues
    {
        get
        {
            return _RightValues;
        }
        set
        {
            if (_RightValues != value)
            {
                _RightValues = value;
                RaisePropertyChanged("RightValues");
            }
        }
    }
}

主:

public List<string> SteelThickness { get; set; }
public List<Selectable> Caliber { get; set; }
public List<GridModel> content4VisualGrid = new List<GridModel>();

public MainWindow()
{
    InitializeComponent();

    SteelThickness = new List<string> { "0.3750", "0.4375", "0.5000", "0.6250", "0.7500", "0.8650", "1.0000" };

    Caliber = new List<Selectable> { new Selectable("0.3750"), 
                                        new Selectable("0.4375"), 
                                        new Selectable("0.5000"), 
                                        new Selectable("0.6250"), 
                                        new Selectable("0.7500"), 
                                        new Selectable("0.8650"), 
                                        new Selectable("1.0001") };

另一个更好的GridModel.cs版本:

public class GridModel : PropertyChangedBase
{
    public int Item { get; set; }

    public string LeftValue { get; set; }

    private Selectable _Selectable;
    public  Selectable Selectable
    {
        get
        {
            return _Selectable;
        }
        set
        {
            if (_Selectable != value)
            {
                _Selectable = value;
                RaisePropertyChanged("Selectable");
            }
        }
    }
}

Selectable.cs:

public class Selectable : PropertyChangedBase
{
    private string _Thickness;
    public  string  Thickness
    {
        get
        {
            return _Thickness;
        }
        set
        {
            if (_Thickness != value)
            {
                _Thickness = value;
                RaisePropertyChanged("Thickness");
            }
        }
    }

    private bool _Enabled;
    public  bool  Enabled
    {
        get
        {
            return _Enabled;
        }
        set
        {
            if (_Enabled != value)
            {
                _Enabled = value;
                RaisePropertyChanged("Enabled");
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

这段代码对我来说很熟悉。我可以在msdn论坛上回答你的问题大声笑吗?

但是,当您在SelectedItem和属性之间设置Binding时,Binding将不会搜索Selectable类中的属性,但您尝试这样做。它为什么绑定在右栏保持喙。用简单的话来说:要查找所选项目中的属性并使用该属性绑定到ComboBox.SelectedItem就像查找内部本身逻辑上没有任何意义lol。再读一遍这句话,你会发现它不可能有效:)

另一方面,SelectedItem和LeftValues之间的绑定将起作用,因为GridModel是每一行的所有者类。

我记得你的msdn代码。你真的弄乱了设计。您没有合适的ViewModel。

我建议你先创建几个非常简单的例子来理解MVVM和WPF的层次思维。

在DataGrid中,GridModel是每行的所有者。在一行中你有ComboBox和SteelThickness作为ItemsSource。把所有这些都放在WPF的层次思维中:GridModel类是SteelThickness的父级。一个SteelTickness用于WPF系统,是一个GridModel实例的子代。

以下是很好的理解MVVM模式的链接:

http://www.codeproject.com/Articles/36545/WPF-MVVM-Model-View-View-Model-Simplified

http://msdn.microsoft.com/en-us/magazine/dd419663.aspx