WPF数据模板不调用get

WPF数据模板不调用get,wpf,xaml,Wpf,Xaml,我必须用两种不同的方法来设置值 如果没有DataTemplate(参数类型),则调用set方法。此列中所有元素的类型相同 对于DataTemplate(值),不调用set方法。我必须使用不同的模板,因为此列中的值来自不同的类型 mainwindow.xaml代码 <Window x:Class="WpfGridTest.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

我必须用两种不同的方法来设置值

  • 如果没有DataTemplate(参数类型),则调用set方法。此列中所有元素的类型相同
  • 对于DataTemplate(值),不调用set方法。我必须使用不同的模板,因为此列中的值来自不同的类型
  • 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>
    

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


    很好的代码转储问题在哪里?你是对的。如果更改该值,则不会调用ParameterViewModel.cs中“value”的set属性。我做错了什么?编辑问题,人们不会在评论中寻找更正。我不明白。我有一个CellTemplateSelector。请参阅公共类参数TypeTemplateSelector:DataTemplateSelector准确地测试它。CellTemplate是只读的。当单元格获得焦点时,它会将模板更改为CellEditingTemplate。看这里:谢谢,现在它工作了。但是如何对同一DataGridTemplateColumn使用CellTemplateSelector和CellEditingTemplateSelector?如果我只使用CellEditingTemplateSelector,则不会显示任何值。如果我同时使用这两种方法,就不会调用Setter。
    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();
            }
        }
     }
    
       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)); }
                }
            }
        }
    
    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>();
    }
    
    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);
            }
        }
    }