1. ホーム
  2. wpf

[解決済み] WPFのDataGridColumnのバインディングの可視性

2023-05-17 08:50:03

質問

WPFのカラムを隠すにはどうしたらよいでしょうか。 DataGrid にある列をバインディングで隠すことはできますか?

これは私がやったことです。

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

そして、これは私が得たものです(列がまだ表示されている以外に)。

System.Windows.Data Error: 2 : ターゲット要素に対して、統治された FrameworkElement または FrameworkContentElement を見つけることができません。BindingExpression:Path=MyColumnVisibility; DataItem=null; target element is 'DataGridTextColumn' (HashCode=1460142); target property is 'Visibility' (type 'Visibility').

バインディングを修正する方法は?

どのように解決するのですか?

まず最初に DataGridTextColumn (または他のサポートされた dataGrid カラム) の Visual ツリーにはありません。 DataGrid . したがって、デフォルトでは を継承しません。 DataContextDataGrid . しかし、それは Binding DPのみで、DataGridColumnの他のDPでは動作しません。

これらは同じVisualTreeに存在しないため、どのような試みでも DataContext を使用して RelativeSource ではうまくいきません。 DataGridTextColumn までトラバースすることができないからです。 DataGrid .

この他にも2つの方法がありますが。


最初の を使って Freezable クラスを使っています。 Freezable オブジェクトは、視覚的または論理的なツリーにない場合でもDataContextを継承することができます -我々はそれを利用することができます。

まず、DataContextを継承したクラスを作成します。 FreezableData というように、XAMLでバインドするために使用することができるDP。

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

さて、DataGridのリソースにそのインスタンスを追加して、DataGridのDataContextを継承して、そのData 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>


第二 を使用すると、XAMLで任意のUI要素を参照することができます。 ElementName または x:Reference . しかし ElementName は同じビジュアルツリーの中でしか機能しませんが、x:Referenceにはそのような制約はありません。

というわけで、これも有利に使うことができます。ダミーの FrameworkElement を XAML で作成し、Visibility を collapsed . FrameworkElement は親コンテナ(Window または UserControl)から DataContext を継承します。

そして、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>