developer tip

WPF의 DataGridColumn에 대한 바인딩 가시성

optionbox 2020. 12. 3. 07:46
반응형

WPF의 DataGridColumn에 대한 바인딩 가시성


DataGrid바인딩을 통해 WPF에서 열을 숨기려면 어떻게 해야합니까?

이것이 내가 한 일입니다.

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

그리고 이것은 내가 얻은 것입니다 (열이 여전히 보이는 것 외에).

System.Windows.Data 오류 : 2 : 대상 요소에 대한 관리 FrameworkElement 또는 FrameworkContentElement를 찾을 수 없습니다. BindingExpression : Path = MyColumnVisibility; DataItem = null; 대상 요소는 'DataGridTextColumn'입니다 (HashCode = 1460142). 대상 속성은 'Visibility'( 'Visibility'유형)입니다.

통치가 무엇을 의미하는지 모릅니다. 내 창문 어딘가에 어떤 것이 효과가 있고 어떤 것이 효과가 없는지 결정하는 대통령이 있습니까? 아니면 투표를해야합니까?

웹에서 해결책을 찾아보다가 제목이 유망하지만 전혀 관련이 없거나 재현 할 수없는 내용을 가진 수십 페이지를 발견했습니다. 그래서 이것이 문제에 대한 첫 번째 질문 인 것 같습니다. 어떤 생각?


우선 DataGridTextColumn또는 지원되는 다른DataGrid 모든 dataGrid 열은 . 따라서, 기본적으로 그것은 상속하지 않습니다 DataContextDataGrid . 그러나 BindingDP에서만 작동 하고 DataGridColumn의 다른 DP 에서는 작동 하지 않습니다.

왜냐하면 그들은 동일한 VisualTree에 RelativeSource있지 않기 때문에 DataGrid가 DataGrid까지 이동할 수 없기 때문에 DataContext를 사용하려는 시도 가 제대로 작동하지 않습니다.

하지만이를 달성하는 방법에는 두 가지가 있습니다.


먼저Freezable 클래스 사용 - Freezable개체는 시각적 또는 논리적 트리에없는 경우에도 DataContext를 상속 할 수 있습니다. 그래서 우리는 그것을 우리의 사용에 활용할 수 있습니다.

먼저 XAML에서 바인딩하는 데 사용할 수있는 DP FreezableDataDP 에서 상속하는 클래스를 만듭니다 .

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에는 이러한 제약이 없습니다.

그래서 우리는 그것을 우리에게 유리하게 사용할 수 있습니다. FrameworkElementVisibility가 축소됨으로 설정된 XAML에서 더미 만듭니다 . 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();
    }
}

참고 URL : https://stackoverflow.com/questions/22073740/binding-visibility-for-datagridcolumn-in-wpf

반응형