バインディングを介してWPF DataGrid
の列を非表示にするにはどうすればよいですか?
これは私がやったことです:
<DataGridTextColumn Header="Column header"
Binding="{Binding ColumnValue}"
Width="100"
ElementStyle="{StaticResource DataGridRightAlign}"
Visibility="{Binding MyColumnVisibility}" />
そして、これは私が得たものです(列がまだ表示されていることに加えて):
System.Windows.Dataエラー:2:ターゲット要素の管理FrameworkFrameworkまたはFrameworkContentElementが見つかりません。 BindingExpression:Path = MyColumnVisibility; DataItem = null;ターゲット要素は 'DataGridTextColumn'(HashCode = 1460142);ターゲットプロパティは 'Visibility'(タイプ 'Visibility')です
統治の意味がわからない。私の窓のどこかに、何が機能し何が機能しないかを決定する大統領がいますか?または、何かに投票する必要がありますか?
Webで解決策を検索しているときに、タイトルは有望だが、まったく無関係または再現不可能なコンテンツを含む12ページほどが見つかりました。したがって、これが問題に関する最初の質問のようです。何か案が?
まず、DataGridTextColumn
またはサポートされている他のdataGrid列は、DataGrid
のビジュアルツリーにありません。したがって、デフォルトではDataContext
のDataGrid
を継承しません。ただし、Binding
DPでのみ機能し、DataGridColumn上の他のDPでは機能しません。
なぜなら、それらは同じVisualTreeにないので、RelativeSource
を使用してDataContextを取得しようとしても、DataGridはDataGridまで移動できないため、同様に機能しません。
ただし、それを実現するには2つの方法があります。
最初Freezable
クラスを使用-Freezable
オブジェクトは、ビジュアルツリーまたは論理ツリーにない場合でもDataContextを継承できます。そのため、それを利用して利用することができます。
XAMLでバインドするために使用できるFreezable
およびData
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リソースに追加して、DataGridのDataContextを継承し、そのデータ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>
Second、ElementName
またはx:Reference
を使用してXAMLの任意のUI要素を参照できます。ただし、ElementName
は同じビジュアルツリーでのみ機能しますが、x:Referenceにはこのような制約はありません。
そのため、それを有利に使用することもできます。 Visibilityをcollapsedに設定して、XAMLでダミーFrameworkElement
を作成します。 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>
<Window.Resources>
<ResourceDictionary>
<FrameworkElement x:Key="ProxyElement" DataContext="{Binding}" />
</ResourceDictionary>
</Window.Resources>
<!-- Necessary for binding to resolve: adds reference to ProxyElement to tree.-->
<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>
ビューモデルのバインドプロパティのサンプル:
private Visibility _isShowName;
public Visibility IsShowName
{
get { return _isShowName; }
set
{
_isShowName = value;
OnPropertyChanged();
}
}