Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf DataContext集合后的DataTemplate选择器_Wpf_Contentcontrol_Datatemplateselector - Fatal编程技术网

Wpf DataContext集合后的DataTemplate选择器

Wpf DataContext集合后的DataTemplate选择器,wpf,contentcontrol,datatemplateselector,Wpf,Contentcontrol,Datatemplateselector,我有一个有两列的数据网格。基于绑定到ParameterDataType的第一列,我希望在第二列中加载适当的模板 此代码的问题在于,在加载DataGrid之前,模板选择器正在执行,因此该项为null。设置ControlTemplate的DataContext后是否有方法执行模板选择器。请帮忙 这是我的xaml: <uwpControls:DataGrid Grid.Row="4" ItemsSource="{x:Bind ViewM

我有一个有两列的数据网格。基于绑定到ParameterDataType的第一列,我希望在第二列中加载适当的模板

此代码的问题在于,在加载DataGrid之前,模板选择器正在执行,因此该项为null。设置ControlTemplate的DataContext后是否有方法执行模板选择器。请帮忙

这是我的xaml:

<uwpControls:DataGrid Grid.Row="4"
                              ItemsSource="{x:Bind ViewModel.ServiceMethodsData,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                               AutoGenerateColumns="False">

<uwpControls:DataGrid.Resources>
                <DataTemplate x:Key="StringTemplate">
                    <TextBox Width="150" Height="30" VerticalAlignment="Center"></TextBox>
                </DataTemplate>
                <DataTemplate x:Key="IntegerTemplate">
                    <controls:TextBoxNumeric Width="150" Height="30" VerticalAlignment="Center"></controls:TextBoxNumeric>
                </DataTemplate>
                <DataTemplate x:Key="BooleanTemplate">
                    <CheckBox IsChecked="False"></CheckBox>
                </DataTemplate>
                <local:MethodValueDataTemplateSelector x:Key="MethodValueTemplateSelector"
                                               StringTemplate="{StaticResource StringTemplate}"
                                               IntegerTemplate="{StaticResource IntegerTemplate}"
                                               BooleanTemplate="{StaticResource BooleanTemplate}"/>
            </uwpControls:DataGrid.Resources>

 <uwpControls:DataGrid.Columns>

                <uwpControls:DataGridTextColumn Header="First Column"  
                                                Binding="{Binding ParameterDataType, Mode=OneWay}"/>

                <uwpControls:DataGridTemplateColumn Header="Second Column">
                    <uwpControls:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ContentControl x:Name="MethodValueContentControl"
                                            Content="{Binding Path=.}"
                                            ContentTemplateSelector="{StaticResource MethodValueTemplateSelector}"></ContentControl>
                        </DataTemplate>
                    </uwpControls:DataGridTemplateColumn.CellTemplate>
                </uwpControls:DataGridTemplateColumn>
            </uwpControls:DataGrid.Columns>
        </uwpControls:DataGrid>
这是我的视图模型

public class ServiceUtilityMethodsViewModel
{
        private ObservableCollection<VmServiceMethodsViewDataGridModel> _serviceMethodsData;
        public ObservableCollection<VmServiceMethodsViewDataGridModel> ServiceMethodsData
        {
            get => _serviceMethodsData;
            set => Set(ref _serviceMethodsData, value);
        }

        public ServiceUtilityMethodsViewModel(INavigationService navigationService) : base(navigationService)
        {
            PopulateServiceData();
        }

        private void PopulateServiceData()
        {
            ServiceMethodsData = new ObservableCollection<VmServiceMethodsViewDataGridModel>();
            ServiceMethodsData.Add(new VmServiceMethodsViewDataGridModel()
            {
                ParameterName = "Param1",
                ParameterDataType = "String"
            });
            ServiceMethodsData.Add(new VmServiceMethodsViewDataGridModel()
            {
                ParameterName = "Param2",
                ParameterDataType = "Int"
            });
            ServiceMethodsData.Add(new VmServiceMethodsViewDataGridModel()
            {
                ParameterName = "Param3",
                ParameterDataType = "bool"
            });
        }
    }
}

您应该直接将
DataTemplateSelector
分配给
DataGridTemplateColumn.CellTemplateSelector
DataGridTemplateColumn.CellEditingTemplateSelector

我没有检查UWP版本。我认为UWP
DataGridTemplateColumn
没有此模板选择器属性。在这种情况下,您可以坚持使用当前的XAML,但不要忘记也定义
CellEditingTemplate
(例如,对于
CellEditingTemplate
版本,将
TextBlock
替换为
TextBox
,最好在默认的
CellTemplate
中使用
TextBlock
,因为它看起来更好)。UWP版本中肯定存在属性
CellTemplate
CellEditingTemplate

XAML
DataGrid
definition

<uwpControls:DataGrid ItemsSource="{x:Bind ViewModel.ServiceMethodsData,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                      AutoGenerateColumns="False">
  <uwpControls:DataGrid.Resources>
    <DataTemplate x:Key="StringTemplate">
      <TextBox Width="150" Height="30" VerticalAlignment="Center" />
    </DataTemplate>
    <DataTemplate x:Key="IntegerTemplate">
      <controls:TextBoxNumeric Width="150" Height="30" VerticalAlignment="Center" />
    </DataTemplate>
    <DataTemplate x:Key="BooleanTemplate">
      <CheckBox IsChecked="False" />
    </DataTemplate>

    <local:MethodValueDataTemplateSelector x:Key="MethodValueTemplateSelector"
                                           StringTemplate="{StaticResource StringTemplate}"
                                           IntegerTemplate="{StaticResource IntegerTemplate}"
                                           BooleanTemplate="{StaticResource BooleanTemplate}" />
  </uwpControls:DataGrid.Resources>

  <uwpControls:DataGrid.Columns>
    <uwpControls:DataGridTextColumn Header="First Column"  
                                    Binding="{Binding ParameterDataType, Mode=OneWay}" />
    <uwpControls:DataGridTemplateColumn Header="Second Column"
                                        CellTemplateSelector="{StaticResource MethodValueTemplateSelector}"
                                        CellEditingTemplateSelector="{StaticResource MethodValueTemplateSelector}">
    </uwpControls:DataGridTemplateColumn>
  </uwpControls:DataGrid.Columns>
</uwpControls:DataGrid>

谢谢,它在Wpf项目中运行良好,但在UWP中,当我分配单元格编辑模板时,它会抛出一个错误。我将尝试使用简单的listview而不是toolkits DataGrid。错误消息是什么?也许我们能解决它。但是如果
列表视图
对您来说已经足够了,那么为什么还要麻烦呢?除非是为了理解。是的,一个简单的列表视图就可以了。但我只是想尝试使用DataGrid。当我尝试分配CellEditingTemplate时,它说,未能将属性分配给uwpToolKit.CellEditing模板。内部异常为null。同样的代码,我创建了一个Wpf项目,它工作得很好。我使用DataGrid的唯一原因是它显示了网格线。我刚刚用ListView试用了它,它也工作得很好。这是UWPTOLKIT唯一的细胞编辑模板。
public class VmServiceMethodsViewDataGridModel : BindableBaseThreadSafe
    {
        private string _parameterName;
        private string _parameterDataType;

        public string ParameterName
        {
            get => _parameterName;
            set => Set(ref _parameterName, value);
        }
        public string ParameterDataType //I want the template selector to work based on this column.
        {
            get => _parameterDataType;
            set => Set(ref _parameterDataType, value);
        }
    }
<uwpControls:DataGrid ItemsSource="{x:Bind ViewModel.ServiceMethodsData,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                      AutoGenerateColumns="False">
  <uwpControls:DataGrid.Resources>
    <DataTemplate x:Key="StringTemplate">
      <TextBox Width="150" Height="30" VerticalAlignment="Center" />
    </DataTemplate>
    <DataTemplate x:Key="IntegerTemplate">
      <controls:TextBoxNumeric Width="150" Height="30" VerticalAlignment="Center" />
    </DataTemplate>
    <DataTemplate x:Key="BooleanTemplate">
      <CheckBox IsChecked="False" />
    </DataTemplate>

    <local:MethodValueDataTemplateSelector x:Key="MethodValueTemplateSelector"
                                           StringTemplate="{StaticResource StringTemplate}"
                                           IntegerTemplate="{StaticResource IntegerTemplate}"
                                           BooleanTemplate="{StaticResource BooleanTemplate}" />
  </uwpControls:DataGrid.Resources>

  <uwpControls:DataGrid.Columns>
    <uwpControls:DataGridTextColumn Header="First Column"  
                                    Binding="{Binding ParameterDataType, Mode=OneWay}" />
    <uwpControls:DataGridTemplateColumn Header="Second Column"
                                        CellTemplateSelector="{StaticResource MethodValueTemplateSelector}"
                                        CellEditingTemplateSelector="{StaticResource MethodValueTemplateSelector}">
    </uwpControls:DataGridTemplateColumn>
  </uwpControls:DataGrid.Columns>
</uwpControls:DataGrid>
public class MethodValueDataTemplateSelector : DataTemplateSelector
{
  public DataTemplate StringTemplate { get; set; }
  public DataTemplate IntegerTemplate { get; set; }
  public DataTemplate BooleanTemplate { get; set; }

  protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
  {
    // Return if the control is not loaded yet and the item is therefore null    
    // or the item is of the wrong type
    if (!(item is VmServiceMethodsViewDataGridModel dataModel))
    {
      return null;
    }

    // I want to do something like: 
    // if(DataContext.ParameterDataType=="Int") return IntegerTemplate etc
    switch (dataModel.ParameterDataType)
    {
      case string value when value.Equals("Int", StringComparison.OrdinalIgnoreCase): 
        return IntegerTemplate;
      case string value when value.Equals("String", StringComparison.OrdinalIgnoreCase): 
        return StringTemplate;
      case string value when value.Equals("Bool", StringComparison.OrdinalIgnoreCase): 
        return BooleanTemplate;
      default: 
        return null;
    }
  }
}