Гость
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Зависимый комбобокс не отображает SelectedItem в .Net 4.5 / 8 сообщений из 8, страница 1 из 1
23.12.2015, 14:53
    #39136090
monstrilla
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Зависимый комбобокс не отображает SelectedItem в .Net 4.5
Суть проблемы. Есть комбобокс с категориями, есть зависимый от него с подкатегориями. При открытии окна выбирается категория и подкатегория для каждого айтема в гриде. То есть должно быть Car-Nissan, Fruit-Lemon. Все работает прекрасно в .Net 4.0, а вот в 4.5 возникает проблема. Айтем выбирается только в главном комбобоксе, то есть, комбобоксе категорий. В дочернем (подкатегории) ничего не выбирается. То есть будет Car - пусто, Fruit - пусто. Уже голову сломал что разработчики .Нет "поправили", что привело к такому эффекту. Как бы это пофиксить? Может кто-то знает альтернативный подход для реализации зависимых комбобоксов, который гарантированно работает в .Нет 4.5? Ниже прилагаю весь код, который генерит проблему в .Нет 4.5.

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
<Window x:Class="GridTest.TestWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:Converter="clr-namespace:GridTest"
        Title="TestWindow" 
        Height="300" 
        Width="300">
    <Window.Resources>
        <Converter:CategoryConverter x:Key="CategoryConverter"/>
    </Window.Resources>
        <Grid>
        <DataGrid Name="_dataGrid" 
                  CanUserAddRows="False" 
                  AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTemplateColumn Width="*">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition/>
                                    <ColumnDefinition/>
                                </Grid.ColumnDefinitions>
                                <ComboBox Grid.Column="0" 
                                          Name="_categories" 
                                          ItemsSource="{Binding Categories}" 
                                          DisplayMemberPath="Name" 
                                          SelectedItem="{Binding SelectedCategory, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
                                </ComboBox>
                                <ComboBox Grid.Column="1" 
                                          SelectedItem="{Binding SelectedSubcategory, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
                                          DisplayMemberPath="Name">
                                    <ComboBox.ItemsSource>
                                        <MultiBinding Converter="{StaticResource CategoryConverter}">
                                            <Binding Path="Subcategories"/>
                                            <Binding Path="SelectedItem" 
                                                     ElementName="_categories"/>
                                        </MultiBinding>
                                    </ComboBox.ItemsSource>
                                </ComboBox>
                            </Grid>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>



Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
public class CategoryConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            if (values[0] == null) return null;
 
            var subcategories = values[0] as List<Subcategory>;
            if (subcategories == null) return null;
 
            var category = values[1] as Category;
            if (category == null) return subcategories;
 
            return subcategories.Where(g => g.CategoryId == category.Id);
        }
 
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
 
 
    public enum CategoryKinds
    {
        Car = 0,
        Fruit = 1,
    }
 
    public class Category
    {
        public Int32 Id { get; set; }
        public String Name { get; set; }
 
        public override Boolean Equals(object obj)
        {
            var c = obj as Category;
            if (c == null) return false;
 
            return Id == c.Id;
        }
    }
 
    public class Subcategory
    {
        public Int32 Id { get; set; }
        public String Name { get; set; }
        public Int32 CategoryId { get; set; }
 
 
        public override Boolean Equals(object obj)
        {
            var sc = obj as Subcategory;
            if (sc == null) return false;
 
            return Id == sc.Id;
        }
    }
 
    public class DataGridItem 
    {
        public List<Category> Categories { get; set; }
        public Category SelectedCategory { get; set; }
 
        public List<Subcategory> Subcategories { get; set; }
        public Subcategory SelectedSubcategory { get; set; }
 
        public DataGridItem()
        {
            Categories = new List<Category>
            {
                new Category
                {
                    Id = (Int32)CategoryKinds.Car, Name = "Car"
                },
                new Category
                {
                    Id = (Int32)CategoryKinds.Fruit, Name = "Fruit"
                }
            };
 
            Subcategories = new List<Subcategory>
            {
                new Subcategory
                {
                    Id = 1,
                    Name = "Volvo",
                    CategoryId = (Int32) CategoryKinds.Car
                },
                new Subcategory
                {
                    Id = 2,
                    Name = "Nissan",
                    CategoryId = (Int32) CategoryKinds.Car
                },
                new Subcategory
                {
                    Id = 3,
                    Name = "Banana",
                    CategoryId = (Int32)CategoryKinds.Fruit
                },
                new Subcategory
                {
                    Id = 4,
                    Name = "Lemon",
                    CategoryId = (Int32)CategoryKinds.Fruit
                },
            };
        }
    }
 
    /// <summary>
    /// Interaction logic for TestWindow.xaml
    /// </summary>
    public partial class TestWindow : Window
    {
        public List<DataGridItem> GridItems { get; set; }
 
        public TestWindow()
        {
            InitializeComponent();
            DataContext = this;
 
            GridItems = new List<DataGridItem>
            {
                new DataGridItem
                {
                    SelectedCategory = new Category
                    {
                        Id = (Int32)CategoryKinds.Car, Name = "Car"
                    },
                    SelectedSubcategory = new Subcategory
                    {
                        Id = 2,
                        Name = "Nissan",
                        CategoryId = (Int32) CategoryKinds.Car
                    }
                },
                new DataGridItem
                {
                    SelectedCategory = new Category
                    {
                        Id = (Int32)CategoryKinds.Fruit, Name = "Fruit"
                    },
                    SelectedSubcategory = new Subcategory
                    {
                        Id = 4,
                        Name = "Lemon",
                        CategoryId = (Int32) CategoryKinds.Car
                    }
                }
            };
 
            _dataGrid.ItemsSource = GridItems;
        }
    }
...
Рейтинг: 0 / 0
23.12.2015, 15:52
    #39136176
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Зависимый комбобокс не отображает SelectedItem в .Net 4.5
return subcategories.Where(g => g.CategoryId == category.Id);
замените на subcategories.Where(g => g.CategoryId == category.Id).ToList();
...
Рейтинг: 0 / 0
23.12.2015, 16:00
    #39136191
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Зависимый комбобокс не отображает SelectedItem в .Net 4.5
кстати, я проверил ваш код в VS 2012 на FW4.5 у меня всё выбирается нормальное
если выбрать Car, то будет Nissan,Volvo, если Фрукт, то бананы какие то и еще что то
...
Рейтинг: 0 / 0
23.12.2015, 16:01
    #39136194
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Зависимый комбобокс не отображает SelectedItem в .Net 4.5
...
Рейтинг: 0 / 0
23.12.2015, 16:14
    #39136216
monstrilla
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Зависимый комбобокс не отображает SelectedItem в .Net 4.5
Roman Mejtes,

Вы, похоже, не поняли вопроса. Я же пишу, дело не в фильтрации айтемов дочернего комбобокса по выбранному айтему в главном. Фильтрация работает хорошо в любом .нете и без .ToList(). А в том, что не срабатывает SelectedItem в дочернем комбобоксе. На момент загрузки окна должно быть

Car - Nissan
Fruit - Banana

в 4-м .нете так и есть, а в 4.5 будет так

Car - пусто
Fruit - пусто
...
Рейтинг: 0 / 0
23.12.2015, 17:16
    #39136331
monstrilla
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Зависимый комбобокс не отображает SelectedItem в .Net 4.5
Рецепт найден. Правда непонятно как работает, но работает. Присоединяйтесь к обсуждению, если интересно

http://www.cyberforum.ru/wpf-silverlight/thread1623089.html
...
Рейтинг: 0 / 0
23.12.2015, 17:20
    #39136335
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Зависимый комбобокс не отображает SelectedItem в .Net 4.5
monstrilla,

что тут обсуждать? почему при переопределение Equals обязательно переопределение получения хеша? или что?
...
Рейтинг: 0 / 0
23.12.2015, 17:22
    #39136338
monstrilla
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Зависимый комбобокс не отображает SelectedItem в .Net 4.5
Roman Mejtes,

Например, почему для главного комбобокса селектед айтем выбирался и без переопределения хэшкода. И почему не работает вот этот вариант.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
GridItems = new List<DataGridItem>
            {
                new DataGridItem(),
                new DataGridItem()
            };
 
            GridItems[0].SelectedCategory = GridItems[0].Categories[0];
            GridItems[0].SelectedSubcategory = GridItems[0].Subcategories[1];
 
            GridItems[1].SelectedCategory = GridItems[1].Categories[1];
            GridItems[1].SelectedSubcategory = GridItems[1].Subcategories[0];
...
Рейтинг: 0 / 0
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Зависимый комбобокс не отображает SelectedItem в .Net 4.5 / 8 сообщений из 8, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]