ViewModel将通用数据导入datagrid

时间:2016-03-10 14:07:40

标签: c# wpf generics mvvm datagrid

我有一个带有通用值的参数模型类。我想根据值的类型更改datagridcell的样式。我有一个不同类型的参数列表。但我不知道如何将Collection与datagrid绑定。

到目前为止,这是我的代码。

SELECT id, name, email FROM contact GROUP BY id, name, email

和XAML

public class ParameterModel<T> : IParameterModel
{
    public T Value { get; set; }
    public T DefaultValue { get; set; }
    public T MaxValue { get; set; }
    public T MinValue { get; set; }
    public string Name { get; set; }
    public Type Type { get { return typeof(T); } }

}

public interface IParameterModel
{
    string Name { get; set; }
    Type Type { get; }
}

public class ParameterViewModel : ViewModelBase
{
    private ObservableCollection<IParameterModel> _parameters;
    public ObservableCollection<IParameterModel> Parameters
    {
        get { return _parameters; }
        set { Set(ref _parameters, value); }
    }
    public ParameterViewModel(IEnumerable<IParameterModel> parameters)
    {
        _parameters = new ObservableCollection<IParameter>(parameters);
    }
}

public class ParameterMockService
{
    public static List<IParameterModel> GetParameters()
    {
        var ret = new List<IParameterModel>();
        ret.Add(new ParameterModel<int> { Value = 50, Name = "Frequence" });
        ret.Add(new ParameterModel<int> { Value = 10, Name = "Word Count"});
        ret.Add(new ParameterModel<string> { Value = "EA2D", Name = "Command"});
        ret.Add(new ParameterModel<bool> { Value = false, Name = "Activate" });
        return ret;
    }
}

也许我必须在我的参数中为每个不同的类型创建一个ViewModel,但我真的不知道最好的方法。 感谢

1 个答案:

答案 0 :(得分:0)

如果你想使用DataTemplateSelector,这是一种方法。

<DataGridTemplateColumn Header="Value">
    <DataGridTemplateColumn.CellTemplateSelector>
        <local:ParameterDataTemplateSelector />
    </DataGridTemplateColumn.CellTemplateSelector>
</DataGridTemplateColumn>

在这个DataTemplateSelector中,我们使用带有前缀的Type.Name作为XAML中某个地方定义的DataTemplate的名称。

public class ParameterDataTemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        var pm = item as IParameterModel;
        var fe = container as FrameworkElement;
        if (pm != null && fe != null)
        {
            var dt = fe.TryFindResource("ParameterModel" + pm.Type.Name) as DataTemplate; // ParameterModelBoolean, ParameterModelString, ParameterModelInt32, etc...
            if (dt != null)
                return dt;
        }
        return base.SelectTemplate(item, container);
    }
}

可以在几个不同的位置定义DataTemplates。下面,我使用了Window.Resources,但如果它们要在全球范围内使用,它可能在你的app.xaml中:

<Window.Resources>
    <DataTemplate x:Key="ParameterModelBoolean">
        <StackPanel>
            <TextBlock>
                <Run Text="Default Value: " />
                <Run Text="{Binding DefaultValue}" />
            </TextBlock>
            <TextBlock>
                <Run Text="Min Value: " />
                <Run Text="{Binding MinValue}" />
            </TextBlock>
            <TextBlock>
                <Run Text="Max Value: " />
                <Run Text="{Binding MaxValue}" />
            </TextBlock>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="Value:" />
                <CheckBox IsChecked="{Binding Value}" />
            </StackPanel>
        </StackPanel>
    </DataTemplate>
    <DataTemplate x:Key="ParameterModelString">
        <StackPanel>
            <TextBlock>
                <Run Text="Default Value: " />
                <Run Text="{Binding DefaultValue}" />
            </TextBlock>
            <TextBlock>
                <Run Text="Min Value: " />
                <Run Text="{Binding MinValue}" />
            </TextBlock>
            <TextBlock>
                <Run Text="Max Value: " />
                <Run Text="{Binding MaxValue}" />
            </TextBlock>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="String Value:" />
                <TextBox Text="{Binding Value}" />
            </StackPanel>
        </StackPanel>
    </DataTemplate>
    <DataTemplate x:Key="ParameterModelInt32">
        <StackPanel>
            <TextBlock>
            <Run Text="Default Value: " />
            <Run Text="{Binding DefaultValue}" />
            </TextBlock>
            <TextBlock>
            <Run Text="Min Value: " />
            <Run Text="{Binding MinValue}" />
            </TextBlock>
            <TextBlock>
            <Run Text="Max Value: " />
            <Run Text="{Binding MaxValue}" />
            </TextBlock>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="Int32 Value:" />
                <TextBox Text="{Binding Value}" />
            </StackPanel>
        </StackPanel>
    </DataTemplate>
</Window.Resources>

截图:

enter image description here