Widoczność wiązania dla DataGridColumn w WPF

Jak mogę ukryć kolumnę w WPF DataGrid Poprzez oprawę?

Oto co zrobiłem:

<DataGridTextColumn Header="Column header"
                    Binding="{Binding ColumnValue}"
                    Width="100"
                    ElementStyle="{StaticResource DataGridRightAlign}"
                    Visibility="{Binding MyColumnVisibility}" />

I to mam (poza kolumną jeszcze widoczną):

System.Okna.Data Error: 2: Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression: Path=MyColumnVisibility; DataItem=null; elementem docelowym jest ' DataGridTextColumn '(HashCode=1460142); właściwością docelową jest 'Visibility' (Typ "Visibility")

Nie wiem, co znaczy rządzenie. Czy w moim oknie jest jakiś pan prezydent, który decyduje, co działa, a co nie? Czy mam na coś głosować?

Szukając rozwiązań w sieci, znalazłem z tuzin stron z obiecującym tytułem, ale całkowicie niepowiązanymi lub nieproduktywnymi treściami. Więc to wydaje się być pierwsze pytanie o problem. Jakiś pomysł?

Author: Anatoliy Nikolaev, 2014-02-27

2 answers

Po pierwsze DataGridTextColumn lub inne wspierane kolumny dataGrid nie leżą w drzewie wizualnym DataGrid. Dlatego domyślnie nie dziedziczy DataContext z DataGrid. Ale działa tylko dla Binding DP i nie dla innych DP na DataGridColumn.

Ponieważ nie leżą one w tym samym VisualTree, więc każda próba uzyskania DataContext przy użyciu RelativeSource nie będzie działać tak dobrze, ponieważ DataGrid nie będzie w stanie przejść do DataGrid.

Są dwa sposoby, aby to osiągnąć chociaż:


Pierwsze użycie klasy Freezable- Freezable obiekty mogą dziedziczyć DataContext nawet wtedy, gdy nie znajdują się w drzewie wizualnym lub logicznym. Więc możemy to wykorzystać do naszego użytku.

Najpierw Utwórz klasę dziedziczącą z Freezable i Data DP, której możemy użyć do bindowania w XAML:

public class BindingProxy : Freezable
{
    #region Overrides of Freezable

    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }

    #endregion

    public object Data
    {
        get { return (object)GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }

    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object),
                                     typeof(BindingProxy));
}

Teraz dodaj jego instancję do zasobów DataGrid, aby mogła dziedziczyć DataContext DataGrid, a następnie powiązać z jego danymi DP:

    <DataGrid>
        <DataGrid.Resources>
            <local:BindingProxy x:Key="proxy" Data="{Binding}"/>
        </DataGrid.Resources>
        <DataGrid.Columns>
            <DataGridTextColumn Visibility="{Binding Data.MyColumnVisibility,
                                                Source={StaticResource proxy}}"/>
        </DataGrid.Columns>
    </DataGrid>

Po Drugie, możesz odnosić się do dowolnego elementu UI w XAML używając ElementName lub x:Reference. Ale ElementName działa tylko w tym samym drzewie wizualnym, podczas gdy X: Reference nie ma takiego ograniczenia.

Więc możemy to wykorzystać na naszą korzyść. Utwórz atrapę FrameworkElement w XAML z widocznością ustawioną na zwiniętą. Framework dziedziczy DataContext z macierzystego kontenera, którym może być Window lub UserControl.

I może użyć tego w DataGrid:

    <FrameworkElement x:Name="dummyElement" Visibility="Collapsed"/>
    <DataGrid>
        <DataGrid.Columns>
            <DataGridTextColumn Header="Test"
                                Binding="{Binding Name}"
                                Visibility="{Binding DataContext.IsEnable,
                                          Source={x:Reference dummyElement}}"/>
        </DataGrid.Columns>
    </DataGrid>
 124
Author: Rohit Vats,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-08 20:26:50
 <Window.Resources>
        <ResourceDictionary>
            <FrameworkElement x:Key="ProxyElement" DataContext="{Binding}" />
        </ResourceDictionary>
 </Window.Resources>

 <ContentControl Content="{StaticResource ProxyElement}" Visibility="Collapsed" />
     <mch:MCHDataGrid Height="350"
                         AutoGenerateColumns="False"
                         FlowDirection="LeftToRight"
                         ItemsSource="{Binding PayStructures}"
                         SelectedItem="{Binding SelectedItem}">
            <DataGrid.Columns>
                <DataGridTemplateColumn Width="70"
                                        Header="name"
                                        IsReadOnly="True"
                                        Visibility="{Binding DataContext.IsShowName,
                                                             Source={StaticResource ProxyElement}}">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding FieldName}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

            </DataGrid.Columns>
        </mch:MCHDataGrid>

W modelu widoku

 private Visibility _isShowName;
        public Visibility IsShowName
        {
            get { return _isShowName; }
            set
            {
                _isShowName = value;
                OnPropertyChanged();
            }
        }
 8
Author: Meysam Chegini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-08 12:11:34