【问题标题】:Binding ComboBox inside DataGrid to subclass of ObservableCollection using MVVM使用 MVVM 将 DataGrid 内的 ComboBox 绑定到 ObservableCollection 的子类
【发布时间】:2014-09-02 02:08:59
【问题描述】:

我正在编写一个带有 MVVM 设计的 wpf 应用程序。在视图中,我有一个带有组合框列的数据网格。数据网格绑定到“AdvancedSearchQueryObjType”类的 ObservableCollection。我想在这个数据网格中绑定组合框,并带有一个类“ObjTypeList”的列表。我在“AdvancedSearchQueryObjType”中有“ObjTypeList”列表,并在加载视图模型时填充两者。

但我在填充组合框时遇到了困难。请参阅下面的代码:

查看:

<DataGrid Name="dgSearchQuery" 
    ItemsSource="{Binding Path=QueryWindowDetails,Mode=TwoWay}" 
    Height="170" AutoGenerateColumns="False" 
    SelectionMode="Single" SelectionUnit="FullRow" 
    CanUserAddRows="False" CanUserDeleteRows="False">
<DataGrid.Columns>
    <DataGridTemplateColumn Header="Category" Width="150">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <ComboBox DataContext="{Binding 
                 RelativeSource={RelativeSource datatyp:AdvancedSearchQueryObjType}}"
                 ItemsSource="{Binding Path=ObjTypeList}" Width="140">

                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="25" />
                                <ColumnDefinition Width="115" />
                            </Grid.ColumnDefinitions>
                            <Rectangle Grid.Column="0"  Margin="3,0,0,0" 
                                Fill="{Binding Path=Icon, Converter={StaticResource   ImgConv}, 
                                RelativeSource={RelativeSource AncestorType=ComboBoxItem}}" />
                            <Label Grid.Column="1" Content="{Binding Path=Value, 
                                 RelativeSource=
                                {RelativeSource  AncestorType=ComboBoxItem}}" Margin="10,0,0,0"/>
                       </Grid>
                    </DataTemplate>
               </ComboBox.ItemTemplate>
           </ComboBox>
       </DataTemplate>
   </DataGridTemplateColumn.CellTemplate>
   </DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>

查看模型:

public class AddQueryViewModel : ViewModelBase 
{
    private void init() 
    {
        QueryWindowDetails = new ObservableCollection<AdvancedSearchQueryObjType>();
        var types = ERUSDataProvider.Instance.GetAllObjectTypeWithAttribute();
        ObjTypeList = new ObservableCollection<ObjektType>();

        types.ToList().ForEach(o => ObjTypeList.Add(new ObjektType { Key = o.Key,                                                                Value = o.Value,
                                     Image = o.Image, 
                                         Icon = o.Icon }));

        _rowCnt = 0;
        AddRow();
        _currentRow = new AdvancedSearchQueryObjType();
    }

    private void AddRow() 
    {
        RowObject = new AdvancedSearchQueryObjType();
        QueryWindowDetails.Add(RowObject);
        this.ObjTypeList.ToList().ForEach(o => RowObject.ObjTypeList.Add((ObjektType)o));
        _rowCnt += 1;
        RowObject.Id = _rowCnt;
    }
}

public class AdvancedSearchQueryObjType : ViewModelBase 
{
    private ObservableCollection<ObjektType> _objTypeList;
    private ObservableCollection<AttribType> _attribTypeList;
    private ObservableCollection<Operator> _operators;
    private ObservableCollection<bool> _conjunction;
    private bool _isNotDate;
    private bool _isNotValue;
    private Visibility _attribVisibility;

    public int Id { get; set; }

    public ObservableCollection<ObjektType> ObjTypeList 
    { 
        get { return _objTypeList; } 
        set { _objTypeList = value;  OnPropertyChanged("ObjTypeList"); } 
    }

    public ObservableCollection<AttribType> AttribTypeList { 
        get { return _attribTypeList; } 
        set { _attribTypeList = value; 
              OnPropertyChanged("AttribTypeList"); } 
    }

    public ObservableCollection<Operator> Operators { 
        get { return _operators; } 
        set { _operators = value; 
          OnPropertyChanged("Operator"); } 
    }

    public ObservableCollection<bool> Conjunction { 
        get { return _conjunction; } 
        set { _conjunction = value; 
            OnPropertyChanged("Conjunction"); } 
    }

    public bool IsNotDate {
        get { return _isNotDate; }
        set { _isNotDate = value; 
            OnPropertyChanged("IsNotDate");}
    }

    public bool IsNotValue{
        get { return _isNotValue;}
        set { _isNotValue = value;
            OnPropertyChanged("IsNotValue");}
    }

    public Visibility AttribVisibility {
        get { return _attribVisibility; }
        set {_attribVisibility = value;
            OnPropertyChanged("AttribVisibility");
        }
    }

    public AdvancedSearchQueryObjType() {
        ObjTypeList = new ObservableCollection<ObjektType>();
        AttribTypeList = new ObservableCollection<AttribType>();
        Operators = new ObservableCollection<Operator>();
        Conjunction = new ObservableCollection<bool>();
        IsNotDate = true;
        IsNotValue = false;
    }
}

请让我知道我做错了什么?

提前致谢

【问题讨论】:

    标签: wpf mvvm datagrid combobox observablecollection


    【解决方案1】:

    只需删除组合框中的 DataContext 绑定即可。

    在数据网格列模板中,默认绑定指向 ItemsSource 中的当前项:

    <ComboBox ItemsSource="{Binding Path=ObjTypeList}" Width="140" />
    

    但由于您的 DataTemplate 用于编辑(组合框是输入控件),您应该将其放在 &lt;DataGridTemplateColumn.CellEditingTemplate&gt; 而不是 &lt;DataGridTemplateColumn.CellTemplate&gt;

    &lt;DataGridTemplateColumn.CellTemplate&gt; 中,您可以只显示当前值:

    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=SelectedObjType}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <ComboBox SelectedItem="{Binding Path=SelectedObjType}" ItemsSource="{Binding Path=ObjTypeList}" Width="140" />
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
    

    假设,当前值(组合框中的选择)是您的 AdvancedSearchQueryObjType 类中名为 SelectedObjType 的属性。

    所有这些都在documentation绑定到数据部分中得到了很好的解释:

    数据网格中的每一行都绑定到数据源中的一个对象,数据网格中的每一列都绑定到数据对象的一个​​属性。

    看看http://wpftutorial.net/DataGrid.html

    【讨论】:

    • 但是由于我绑定Combobox的对象是不同的类,所以datacontext不应该改变吗???
    • 这就是我试图用“在数据网格列模板中,默认绑定指向 ItemsSource 中的当前项”来解释的内容。这意味着绑定的路径与 AdvancedSearchQueryObjType 列表中的当前对象相关。
    猜你喜欢
    • 2016-08-28
    • 2014-03-18
    • 1970-01-01
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    • 2013-09-07
    • 2021-08-31
    相关资源
    最近更新 更多