2017-04-19 28 views
0

我必須用2種不同的方法來設置一個值。 ScreenshotWPF DataTemplate不會調用獲取

  1. 沒有DataTemplate(參數類型)調用set方法。此列中所有元素的類型相同。
  2. 使用DataTemplate(Value)不會調用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> 

的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

公共類ParameterListViewModel:ViewModelBase { #地區構造

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

不錯的代碼轉儲問題在哪裏? – MikeT

+0

你說得對。 如果更改該值,則不會調用ParameterViewModel.cs中「Value」的set屬性。我究竟做錯了什麼? – Holgis

+0

編輯該問題,人們不看在更正的意見 – MikeT

回答

0

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

獲取或設置對象t帽子決定使用哪個模板來顯示未處於編輯模式的單元格內容。

+0

我不明白。我有一個CellTemplateSelector。請參閱 public class ParameterTypeTemplateSelector:DataTemplateSelector – Holgis

+0

就是這樣。 CellTemplate是隻讀的。當單元格獲得焦點時,它將模板更改爲CellEditingTemplate。看看這裏: https://msdn.microsoft.com/en-us/library/system.windows.controls.datagridtemplatecolumn(v=vs.110).aspx#Anchor_7 – Mishka

+0

謝謝,現在它工作。 但如何可以使用CellTemplateSelector和CellEditingTemplateSelector對於相同DataGridTemplateColumn?如果我只使用CellEditingTemplateSelector,則不會顯示任何值。如果我同時使用,則不會調用Setter。 什麼錯誤? – Holgis