WPF : 8. DataGridColumn의 Visibility 바인딩하는 방법
초기 구현

DataGridColumn의 Visibility속성을 직접 바인딩해서 첫번째 열을 숨긴다.
<DataGrid>
    <DataGrid.Columns>
        <DataGridTextColumn Header="First" 
                            Visibility="{Binding IsFirstColumnVisible}"/>
        <DataGridTextColumn Header="Second"/>
    </DataGrid.Columns>
</DataGrid>
public partial class MainWindow : Window
{
    public Visibility IsFirstColumnVisible { get; set; }
    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        IsFirstColumnVisible = Visibility.Hidden; // 숨기기
    }
}
첫번째 열이 사라지지 않고 다음과 같은 에러가 발생한다.
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=IsFirstColumnVisible; DataItem=null; target element is 'DataGridTextColumn' (HashCode=21800467); target property is 'Visibility' (type 'Visibility')
해결 방법
DataGridColumn은 DataGrid의 Visual Tree에 있지 않으므로 DataGrid의 DataContext를 상속하지 않는다. 또한 Visual Tree에 놓여있지 않으면, RelativeSource를 이용해서 상위 타입을 찾는 방법도 사용할 수 없다. 해결 방법은 Freezable객체는 Visual Tree에 있지 않아도, DataContext를 상속받기 때문에, Freezable객체를 이용하면 된다.
먼저. Freezable클래스를 상속받은 후 의존속성(Data)생성한다.
public class BindingProxy : Freezable
{
    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy));
    public object Data
    {
        get { return GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }
    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }
}
다음으로, DataGrid의 DataContext를 상속받는 Freezable인스턴스를 리소스에 추가하고, DataGridColumn의 Visibility속성과 바인딩한다.
<DataGrid>
    <DataGrid.Resources>
        <local:BindingProxy x:Key="FirstColumnProxy" Data="{Binding IsFirstColumnVisible}"/>
    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridTextColumn Header="First" 
                            Visibility="{Binding Data, Source={StaticResource FirstColumnProxy}}"/>
        <DataGridTextColumn Header="Second"/>
    </DataGrid.Columns>
</DataGrid>
DataGrid의 첫번째 열이 사라진 걸 확인할 수 있다.

댓글남기기