何らかの条件で DataGrid の列を非表示にする必要がある場合、私たちは皆問題に直面しました。この問題を解決するには、少なくとも 2 つの方法があります。どちらのアプローチにもプロキシ要素が必要です。私はこれらのアプローチの両方を使用します。ご覧のとおり、FreezableProxy
プロキシ要素としての使用には は必要ありませんContentControl
が、追加のクラス ( FreezableProxy
) を指定する必要があります。FrameworkElement
をプロキシとして使用する場合、追加のクラス ( などFreezableProxy
) を指定する必要はありませんがContentControl
、マークアップに追加する必要があります。
XAML:
<Window.Resources>
<SampleRadioBoxCheckedConverter:FreezableProxy x:Key="FreezableProxy" Data="{Binding}"/>
<FrameworkElement x:Key="FrameworkElement" DataContext="{Binding}"/>
</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>
分離コード:
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;
}
}
どちらのアプローチも非常に似ています。2 番目のアプローチ (を使用FrameworkElement
) を使用することをお勧めします。次に、質問があります-実際に設定されてContentControl
いる場合、追加を指定する必要があるのはなぜですか? 魔法は何をしているの?使用する場合、何かを指定する必要はなく、正常に機能します。Binding
{StaticResource FrameworkElement}
ContentControl
FrezableProxy
ContentControl-s
アップデート
<FrameworkElement x:Key="FrameworkElement" DataContext="{Binding}"/>
/////<ContentControl Grid.Row="1" Content="{StaticResource FrameworkElement}" Visibility="Collapsed"></ContentControl>
なぜこれが機能しないのですか?ContentControl はコメントされていDataContext
ますが、プロパティをFrameworkElement
明示的に設定しています。