WPF DataTemplate不调用get

时间:2017-04-19 08:58:33

标签: wpf xaml

我有两种不同的方式来设置一个值。 Screenshot

  1. 如果没有DataTemplate(参数类型),则调用set方法。此列中所有元素的类型相同。
  2. 使用DataTemplate(Value)不调用set方法。我必须使用不同的模板,因为此列中的值来自不同的类型。
  3. mainwindow.xaml代码

    <Window x:Class="WpfGridTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:data="clr-namespace:WpfGridTest.MVVM"
        xmlns:system="clr-namespace:WpfGridTest.Common"
        mc:Ignorable="d"
        Title="MainWindow" Height="300" Width="450"
        FontSize="12">
    
    <Window.DataContext>
        <data:ParameterListViewModel/>    
    </Window.DataContext>
    
    <Grid DataContext="{Binding ParameterList}">
        <Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
    
            <ToolBar Grid.Row="0" Background="LightGray">
            </ToolBar>
    
            <DataGrid Grid.Row="1" x:Name="dataGrid" ItemsSource="{Binding}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" 
                      AutoGenerateColumns="False" CanUserAddRows="False">
    
                <DataGrid.Resources>
                    <DataTemplate x:Key="StringTemplate">
                        <TextBox Text="{Binding Value, Mode=TwoWay}" Margin="2" 
                                 Background="GreenYellow" Foreground="Black" />
                    </DataTemplate>
                    <DataTemplate x:Key="EnumTemplate">
                        <ComboBox Margin="2" ItemsSource="{Binding EnumList, Mode=TwoWay}" DisplayMemberPath="Name" SelectedValue="{Binding Value}" SelectedValuePath="Value" 
                                  Background="GreenYellow" Foreground="Black" />
                    </DataTemplate>
                    <DataTemplate x:Key="NumberTemplate">
                        <TextBox Margin="2" Text="{Binding Value, Mode=TwoWay}" 
                                 Background="GreenYellow" Foreground="Black" TextAlignment="Right" />
                    </DataTemplate>
                </DataGrid.Resources>
    
                <DataGrid.Columns>
                    <DataGridTextColumn x:Name="Name" Header="Parameter name" Binding="{Binding Name}"/>
    
                    <DataGridComboBoxColumn x:Name="Type" Header="Parameter type" SelectedValueBinding="{Binding Type}"
                                            ItemsSource="{Binding Source={x:Static data:ParameterListViewModel.GetListOfParameterTypes}}"/>
    
                    <DataGridTemplateColumn Header="Value">
                        <DataGridTemplateColumn.CellTemplateSelector>
                            <system:ParameterTypeTemplateSelector 
                                EnumTemplate="{StaticResource EnumTemplate}" 
                                StringTemplate="{StaticResource StringTemplate}"
                                NumberTemplate="{StaticResource NumberTemplate}"/>
                        </DataGridTemplateColumn.CellTemplateSelector>
    
                    </DataGridTemplateColumn>
    
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Grid>
    

    ParameterModel.cs

    using System;
    using System.Collections.Generic;
    using System.Xml.Serialization;
    using WpfGridTest.Common;
    
    namespace WpfGridTest.MVVM
    {
        public enum ParameterType
        {
            UINT16,
            ENUM16,
            BIT_ENUM16,
            FLOAT,
            DATE,
            STRING
        }
    
        public class EnumItem
        {
            public string Name { get; set; }
            public int Value { get; set; }
        }
    
        public class Parameter : ViewModelBase
        {
            public Parameter()
            {
            }
    
            public Parameter(string name, ParameterType type)
            {
                Name = name;
                Type = type;
            }
    
            public string Name { get; set; }
            public ParameterType Type { get; set; }
            public List<EnumItem> EnumList { get; set; }
            public object Value { get; set; }
    
            public override void OnLoaded()
            {
                throw new NotImplementedException();
            }
    
            public override void OnUnloaded()
            {
                throw new NotImplementedException();
            }
        }
     }
    

    ParameterViewModel.cs

       using System.Collections.Generic;
        using WpfGridTest.Common;
    
        namespace WpfGridTest.MVVM
        {
            public class ParameterViewModel : ViewModelBase
            {
                #region Properties
                private string name;
                public string Name
                {
                    get { return name; }
                    set
                    {
                        name = value;
                        OnPropertyChanged (nameof (Name));
                    }
                }
    
                private ParameterType type;
                public ParameterType Type
                {
                    get { return type; }
                    set { type = value; OnPropertyChanged (nameof (Type)); }
                }
    
                private List<EnumItem> enumlist; 
                public List<EnumItem> EnumList
                {
                    get { return enumlist; }
                    set { enumlist = value; OnPropertyChanged(nameof(EnumList)); 
     }           }
    
                private object _value;
                public object Value
                {
                    get { return _value; }
                    set { _value = value; OnPropertyChanged(nameof(Value)); }
                }
            }
        }
    

    ParameterListViewModel.cs

    public class ParameterListViewModel:ViewModelBase {     #region Constructors

    public ParameterListViewModel()
    {
        List<EnumItem> list1 = new List<EnumItem>
        {
            new EnumItem {Name = "Item 1.1", Value = 1},
            new EnumItem {Name = "Item 1.2", Value = 2},
        };
    
        ParameterList = new ObservableCollection<ParameterViewModel>();
        ParameterList.Add (new ParameterViewModel { Name = "Enum 1", Type = ParameterType.ENUM16, Value=1, EnumList = list1 }) ;
        ParameterList.Add (new ParameterViewModel { Name = "String", Type = ParameterType.STRING, Value="Test String" });
        ParameterList.Add (new ParameterViewModel { Name = "Uint",   Type = ParameterType.UINT16, Value=123 });
    }
    
    private ObservableCollection<ParameterViewModel> parameterlist; 
    public ObservableCollection<ParameterViewModel> ParameterList
    {
        get { return parameterlist;  }
        set
        {
            parameterlist = value;
            OnPropertyChanged (nameof(ParameterList));
        }
    }
    
    public static IEnumerable<ParameterType> GetListOfParameterTypes => Enum.GetValues(typeof(ParameterType)).Cast<ParameterType>();
    }
    

    至少是TemplateSelector类

    namespace WpfGridTest.Common
    {
        public class ParameterTypeTemplateSelector : DataTemplateSelector
        {
            public DataTemplate EnumTemplate       { get; set; }
            public DataTemplate NumberTemplate     { get; set; }
                public DataTemplate StringTemplate { get; set; }
    
            public override DataTemplate SelectTemplate(object item, DependencyObject container)
            {
                //Parameter parameter = item as Parameter;
                ParameterViewModel parameter = item as ParameterViewModel;
    
                if (parameter != null)
                {
                    if ((parameter.Type == ParameterType.ENUM16) || (parameter.Type == ParameterType.BIT_ENUM16))
                        return EnumTemplate;
                    else if ((parameter.Type == ParameterType.STRING))
                        return StringTemplate;
                    else
                        return NumberTemplate;
                }
                else
                    return base.SelectTemplate(item, container);
            }
        }
    }
    

1 个答案:

答案 0 :(得分:0)

https://msdn.microsoft.com/en-us/library/system.windows.controls.datagridtemplatecolumn.celltemplateselector(v=vs.110).aspx

  

获取或设置用于确定用于显示未处于编辑模式的单元格内容的模板的对象。