powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Обсуждение подходов к установке свойства Visibility в колонках DataGrid-а
4 сообщений из 4, страница 1 из 1
Обсуждение подходов к установке свойства Visibility в колонках DataGrid-а
    #38730558
monstrilla
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Наверное всем приходилось сталкиваться с ситуацией, когда нужно скрывать-показывать колонку в DataGrid-e. Многие знают, что колонка в гриде не является частью визуального дерева, посему не наследует DataContext окна, т.е. напрямую к свойству DataContext-a забиндиться нельзя. Так вот, как скрывать-показывать колонку я могу реализовать тремя способами, вопрос не в этом. Вопрос в том, как эти способы работают "внутри". Просто интересно разобраться. Третий способ (через x:Reference) неинтересный, предлагаю сравнить два. Разметка и код прилагаются.

XAML:

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
 <Window.Resources>
        <myNs:FreezableProxy x:Key="FreezableProxy" Data="{Binding}"/>
        <FrameworkElement x:Key="FrameworkElement"/>
    </Window.Resources>
        
    <Grid Margin="10">
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <DataGrid AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name"/>
                <DataGridTextColumn Header="Type" 
                                    Visibility="{Binding Data.IsPartnerColumnVisible, Source={StaticResource FreezableProxy}}"/>
                <DataGridTextColumn Header="Number" 
                                    Visibility="{Binding DataContext.IsPartnerColumnVisible, Source={StaticResource FrameworkElement}}"/>
    
            </DataGrid.Columns>
        </DataGrid>
        <ContentControl Grid.Row="1" Content="{StaticResource FrameworkElement}" Visibility="Collapsed"></ContentControl>
    
    </Grid>




Code-behind:

Код: 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.
public class FreezableProxy : Freezable
    {
        protected override Freezable CreateInstanceCore()
        {
            return new FreezableProxy();
        }
    
        public object Data
        {
            get { return (object)GetValue(DataProperty); }
            set { SetValue(DataProperty, value); }
        }
    
        public static readonly DependencyProperty DataProperty =
            DependencyProperty.Register("Data", typeof(object),
                                            typeof(FreezableProxy));
    }

    public partial class MainWindow : INotifyPropertyChanged
    {
        private Visibility _isPartnerColumnVisible = Visibility.Hidden;
        public Visibility IsPartnerColumnVisible
        {
            get
            {
                return _isPartnerColumnVisible;
            }
            set
            {
                _isPartnerColumnVisible = value;
                RaisePropertyChanged("IsPartnerColumnVisible");
            }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
        void RaisePropertyChanged(String prop)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(prop));
        }
    
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
        }
    }



Оба подхода очень похожи, оба используют прокси-элемент в качестве ресурса. Разница только в типе. Рассмотрим первый подход через FreezableProxy. Как МНЕ видится как это работает. Создается класс, в классе определяется свойство зависимости (чтоб было куда биндить), потом в это свойство биндится DataContext окна, потом из этого свойства извлекается значение DataContext-a. Вроде все логично, вот только если создавать произвольный класс, а не наследник от Freezable, то работать не будет. Почему - непонятно. Вопрос! Буржуи пишут, что Freezable классы наследуют DataContext и фокус в этом. Вот только в классе Freezable нет свойства DataContext вообще как такового и так или иначе используется руками определенное свойство Data. При чем тут DataContext класса Freezable??? Вопрос!

Второй подход через FrameworkElement.

Буржуи пишут, что ContentControl наследует DataContext окна (согласен), FrameworkElement, в свою очередь, наследует DataContext у ContentControla (опять согласен). Таким образом, FrameworkElement имеет DataContext окна и потому строка


Код: xml
1.
Binding DataContext.IsPartnerColumnVisible



правомерна. Тогда получается, что суть ContentControl-a - передавать транзитом DataContext окна FrameworkElemet-у. У меня возникает логичный вопрос, а почему сразу не написать так

Код: xml
1.
<FrameworkElement x:Key="FrameworkElement" DataContext="{Binding}"/>



пробовал, не работает. Почему? Вопрос!
...
Рейтинг: 0 / 0
Обсуждение подходов к установке свойства Visibility в колонках DataGrid-а
    #38730749
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
monstrillaпробовал, не работает. Почему? Вопрос!Вопрос из разряда "почему вода мокрая". Ну нужно искать смысл там, где его нет. Да никто и не обещал, что ресурсы будут наследовать DataContext.

Можно описать ViewModel в ресурсах и без проблем биндиться к ней напрямую через StaticResource.
Код: xml
1.
2.
3.
4.
5.
     <Window.Resources>
        <my:ViewModel x:Key="viewModel"/>
     </Window.Resources>

    <DataGridTextColumn Visibility="{Binding IsPartnerColumnVisible, Source={StaticResource viewModel}}"/>


Если нужен именно DataContext, то можно попробовать ещё такой вариант:
Код: xml
1.
<DataGridTextColumn Visibility="{Binding DataContext.IsPartnerColumnVisible, Source={DocumentRoot}}"/>

DocumentRootExtension
...
Рейтинг: 0 / 0
Обсуждение подходов к установке свойства Visibility в колонках DataGrid-а
    #38730797
monstrilla
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Алексей К,

нормальный вопрос :) я, кстати, разобрался, точнее мне таки объяснили буржуи

авторДа никто и не обещал, что ресурсы будут наследовать DataContext.

угу, вот только я был не в курсе. Именно поэтому, ресурс типа Framework элемента нужно где-то размещать в визуальном дереве. ТОгда он понимает, что DataContext нужно наследовать. А Freezable класс хитро реализован и таки наследует DataContext, даже если НЕ является частью визуального дерева (на мсдн, кстати, про это ни слова). Если это принять как данность - вопросы отпадают.
...
Рейтинг: 0 / 0
Обсуждение подходов к установке свойства Visibility в колонках DataGrid-а
    #38730833
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
monstrillaА Freezable класс хитро реализован и таки наследует DataContext, даже если НЕ является частью визуального дерева (на мсдн, кстати, про это ни слова). Если это принять как данность - вопросы отпадают. Тут
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Обсуждение подходов к установке свойства Visibility в колонках DataGrid-а
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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