DataTemplated DataGrid не связывается правильно? DataTemplateSelector.SelectTemplate получает значение null как «элемент» - PullRequest
0 голосов
/ 02 ноября 2019

Так что я пытаюсь создать пользовательский стиль DataGrid с DataTemplateSelector. Я новичок в WPF и связывании, так что я, вероятно, делаю что-то не так.

Объект item, полученный в качестве параметра функции SelectTemplate, всегда имеет значение null.

Я пытался найти эту проблему, но не могу найти ответ.

XAML:

        <Grid.Resources>
            <!-- Default DataTemplate -->
            <DataTemplate x:Key="DefaultDataTemplate">
                <TextBlock Text="{Binding Path=Value}" />
            </DataTemplate>

            <!-- DataTemplate for Booleans -->
            <DataTemplate x:Key="BooleanDataTemplate">
                <CheckBox IsChecked="{Binding Path=Value, Mode=TwoWay}" />
            </DataTemplate>

            <!-- DataTemplate for Arrays -->
            <DataTemplate x:Key="ArrayDataTemplate">
                <ComboBox ItemsSource="{Binding Path=Value, Mode=TwoWay}" />
            </DataTemplate>

            <local:ValueDataTemplateSelector x:Key="templateSelector" 
                   DefaultDataTemplate="{StaticResource DefaultDataTemplate}" 
                   BooleanDataTemplate="{StaticResource BooleanDataTemplate}" 
                   ArrayDataTemplate="{StaticResource ArrayDataTemplate}" />

        </Grid.Resources>

        <DataGrid Name="DG1" ItemsSource="{Binding TagListView}" AutoGenerateColumns="False" >
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" />
                <DataGridTemplateColumn Header="Value" CellTemplateSelector="{StaticResource templateSelector}" CellEditingTemplateSelector="{StaticResource templateSelector}" />
            </DataGrid.Columns>
        </DataGrid>

код позади:

    public partial class TestView : Window
    {
        public TestView()
        {
            var t = new TestViewModel();
            DataContext = t;
            InitializeComponent();


        }
    }

модель представления:

    class TestViewModel
    {

        public TestViewModel()
        {
            generateTestList();
            TagListView = new ListCollectionView(testList);
        }

        private ObservableCollection<TestTag> testList;

        private void generateTestList()
        {
            testList = new ObservableCollection<TestTag>();

            bool b = false;
            testList.Add(new TestTag("bool", (object)b, b.GetType()));

            string s = "...";
            testList.Add(new TestTag("string", (object)s, s.GetType()));

            ushort ui = (ushort)100u;
            testList.Add(new TestTag("uint16", (object)ui, ui.GetType()));

            int[] i_arr = new int[] { 1, 2, 3 };
            testList.Add(new TestTag("int[]", (object)i_arr, i_arr.GetType()));



        }
        public ListCollectionView TagListView { get; private set; }
}

DataTemplateSelector. Параметр "item" для SelectTemplate всегда равен нулю

public class ValueDataTemplateSelector : DataTemplateSelector
    {
        public DataTemplate DefaultDataTemplate { get; set; }
        public DataTemplate BooleanDataTemplate { get; set; }
        public DataTemplate ArrayDataTemplate { get; set; }

        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            var tag = item as TestTag;

            Type t = tag.Type;

            if (t == typeof(bool))
                return BooleanDataTemplate;

            if (t == typeof(int[]))
                return ArrayDataTemplate;

            return DefaultDataTemplate;
        }
    }

модель

    class TestTag : INotifyPropertyChanged
    {

        private string _Name;
        private object _Value;
        public Type Type;

        public string Name
        {
            get { return _Name; }
            private set
            {
                _Name = value;
                NotifyPropertyChanged("Name");
            }
        }

        public object Value
        {
            get
            {
                return _Value;
            }

            set
            {
                _Value = value;
                NotifyPropertyChanged("Value");
            }
        }

1 Ответ

0 голосов
/ 02 ноября 2019

Похоже, что вы просто пропускаете нулевую проверку в методе SelectTemplate:

public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            var tag = item as TestTag;
            if(tag == null)
                return DefaultDataTemplate;
            Type t = tag.Type;
            if (t == typeof(bool))
                return BooleanDataTemplate;
            if (t == typeof(int[]))
                return ArrayDataTemplate;
            return DefaultDataTemplate;
        }

Вы можете также рассмотреть возможность очистки до вашего TestTag класса модели, например, используйте genericчем объект типа, потерять свойство Type и использовать typeof когда нужно ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...