简体   繁体   English

将DataGrid绑定到ModelWrapper的ObservableCollection <Model>

[英]Binding DataGrid to ObservableCollection of ModelWrapper<Model>

Auto-Generating Columns for the Properties of a Wrapped-Object 自动生成包装对象属性的列

I am wanting to have AutoGeneratedColumns="true" but my I'm not sure how to do this with this ModelWrapper design. 我想拥有AutoGeneratedColumns =“ true”,但我不确定如何使用此ModelWrapper设计来做到这一点。 (I'm following the early stages of PluralSight.com's "Advanced Model Treatment" course). (我正在遵循PluralSight.com的“高级模型处理”课程的早期阶段)。

My <datagrid> in a working state (This has manually defined columns, but I want autogenerated columns - while persisting with this ModelWrapper pattern): 我的<datagrid>处于工作状态(这具有手动定义的列,但是我想要自动生成的列-同时坚持使用此ModelWrapper模式):

<DataGrid Grid.Row="0"
          Grid.RowSpan="2"
          Grid.Column="1"
          DockPanel.Dock="Top"
          ItemsSource="{Binding Segments}"
          SelectionUnit="FullRow" 
          AutoGenerateColumns="False">      

         <DataGrid.Columns>
             <DataGridTextColumn Header="Name" Width="1*" Binding="{Binding Model.Name}"/>
             <DataGridTextColumn Header="Notes" Width="2*" Binding="{Binding Model.Notes}"/>
        </DataGrid.Columns>

</DataGrid>

Note: that the DataContext for the <datagrid> above (ie the associated ViewModel) exposes an ObservableCollection<ModelWrapper<Segment>> called Segments . 注意:上面<datagrid>的DataContext(即关联的ViewModel)公开了一个称为SegmentsObservableCollection<ModelWrapper<Segment>>

Here is my ModelWrapper class that is used to wrap a basic class with only CLR properties (I hazard a guess the problem is not here - or in my model definition further below): 这是我的ModelWrapper类,该类用于包装仅具有CLR属性的基本类(我敢猜测这个问题不在这里-或在下面的我的模型定义中):

Note: Observable implements INotifyPropertyChanged . 注意: Observable实现INotifyPropertyChanged

internal class ModelWrapper<T> : Observable
{
    public ModelWrapper(T model)
    {
        if (model == null)
            throw new ArgumentNullException(nameof(model));
        Model = model;
    }

    public T Model { get; }

    protected void SetValue<TValue>(TValue value, [CallerMemberName] string propertyName = null)
    {
        var propertyInfo = Model.GetType().GetProperty(propertyName);
        var currentValue = propertyInfo.GetValue(Model);
        if (Equals(currentValue, value)) return;
        propertyInfo.SetValue(Model, currentValue);
        OnPropertyChanged(propertyName);
    }

    protected TValue GetValue<TValue>([CallerMemberName] string propertyName = null)
    {
        var propertyInfo = Model.GetType().GetProperty(propertyName);
        return (TValue) propertyInfo.GetValue(Model);
    }
}

Here is the model class that is wrapped by the ModelWrapper: 这是由ModelWrapper包装的模型类:

internal class Segment
{
    public string Notes { get; set; }
    public string Name  { get; set; }
}

If I set AutoGenerateColumns to True , then I only get one column with the Header ...Model (ie ToString() -ing the Model object). 如果我将AutoGenerateColumns设置为True ,那么我只会获得带有Header ...Model一列(即ToString() ing Model对象)。

I've rushed ahead of the course and am trying to implement something with the ModelWrapper pattern. 我急于完成课程,并尝试使用ModelWrapper模式实现某些功能。 Can I autogenerate the columns, as per the properties of the ordinaryCLRobject? 是否可以根据normalCLRobject的属性自动生成列?

How? 怎么样? What and I doing wrong? 我做错了什么? ... thanks in advance. ... 提前致谢。 :-) :-)

My problem was that I was creating ObservableCollections of type ModelWrapper instead of, in my case, SegmentWrapper : ModelWrapper<Segment> . 我的问题是我正在创建ModelWrapper类型的ObservableCollections ,而不是SegmentWrapper : ModelWrapper<Segment>

I can then remove Model. 然后,我可以删除Model. from the binding path in my xaml columns, ie: 从我的xaml列中的绑定路径开始,即:

        <DataGrid.Columns>
             <DataGridTextColumn Header="Name" Width="1*" Binding="{Binding Name}"/>
             <DataGridTextColumn Header="Notes" Width="2*" Binding="{Binding Notes}"/>
        </DataGrid.Columns>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM