DataContext设置后的DataTemplate选择器

问题描述 投票:1回答:1

我有一个包含2列的DataGrid。基于绑定到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>

这是我的DataTemplate选择器

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)
        {
            //I want to do something like if(DataContext.ParameterDataType=="Int") return IntegerTemplate etc
            return StringTemplate;
        }
    }

这是我的ViewModel

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"
            });
        }
    }
}

这是我的模型班

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);
        }
    }
wpf contentcontrol datatemplateselector
1个回答
1
投票

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

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

XAML CellEditingTemplate定义

DataGrid

<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> 也很简单。DataTemplateSelector替代的参数是商品和商品的容器(大部分时间是SelectTemplateCoreFrameWorkElement)。该项目始终是数据模型和当前行的ContentControl。在您的情况下,该项目的类型为DataContext

容器是VmServiceMethodsViewDataGridModel,用于包装模型以进行渲染,例如FrameWorkElement。根据您的情况,容器的类型应为ListBoxItem

简单地将item参数转换为适当的类型并求值。

MethodValueDataTemplateSelector.cs

DataGridRow
© www.soinside.com 2019 - 2024. All rights reserved.