如何将DataGridTemplateColumn.Visibility绑定到DataGrid.ItemsSource之外的属性?

19

我需要将DataGridTemplateColumnVisibility绑定到DataGrid.ItemsSource之外的属性,因为我需要将此列绑定到ViewModel内的一个属性,而不仅仅是ItemsSource中的一些内容。但据我所知,您只能将其绑定到ItemsSource中的某个内容,或者使用ElementStyleEditingElementStyle

我已经尝试过以下代码:

 <DataGridTemplateColumn Header="post" 
                      Visibility="{Binding DataContext.ProjectPostVisibility
                    , RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=MvvmCommonControl:DataGrid}}"/>

我相信我的绑定是正确的,因为当我像下面这样绑定DataGridCell.Visibility时,它可以正常工作:

And i'm Sure my binding is correct because it works fine when i bind the DataGridCell.Visibility like below:
<DataGridTemplateColumn Header="post">
    <DataGridTemplateColumn.CellStyle>
                        <Style TargetType="DataGridCell">
                            <Setter Property="Visibility" Value="{Binding DataContext.ProjectPostVisibility,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=MvvmCommonControl:DataGrid}}"/>
                        </Style>
                    </DataGridTemplateColumn.CellStyle>
</DataGridTemplateColumn >

你能展示一些代码吗? - Abdusalam Ben Haj
@ AbZy:我在上面添加了一些代码。 - mahboub_mo
3个回答

27

您的绑定是正确的,但是它无法直接使用DataGridTemplateColumn,因为它不在可视树中。因此,它没有继承DataContext

您需要从代码后台绑定DataGridTemplateColumn这里有一个演示展示了一种方法。


AbZy:非常感谢。我之前不知道这个,真的很有趣! - mahboub_mo

9

如其他答案所述,该列并非可视/逻辑树的一部分,并且不继承自FrameworkElement,这意味着它没有DataContext。这就是为什么你的绑定不起作用。

但是,您可以在DataContext符合要求的级别(因此以您的示例为例,它将位于DataGrid的级别)添加一个虚拟(折叠的)FrameworkElement,将其折叠起来并将其用作绑定的源,使用x:Reference标记扩展。

以下是示例:

<FrameworkElement x:Name="Proxy" Visibility="Collapsed"/>
<DataGrid>
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="post" 
            Visibility="{Binding DataContext.ProjectPostVisibility, Source={x:Reference Name=Proxy}}"/>
    </DataGrid.Columns>
</DataGrid>

5
在 DataGridTemplateColumn.CellStyle 中添加此 setter 即可完成:
   <Setter Property="Visibility" Value="{Binding DataContext.isVisible, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}"/>

如果您需要更多帮助,请参考下面的示例。 我想在项目级别上不显示删除按钮。 首先,您必须确保视图模型中有一个isVisible属性:

  private System.Windows.Visibility _isVisible;
    public System.Windows.Visibility isVisible
    {
        get { return _isVisible; }
        set
        {
            if (_isVisible != value)
            {
                _isVisible = value;
                OnPropertyChanged("isVisible");
            }
        }
    }

然后:

  if (isProj == false)
            this.model.isVisible = Visibility.Visible;
        else
            this.model.isVisible = Visibility.Collapsed;

XAML:

<DataGridTemplateColumn  >
       <DataGridTemplateColumn.CellTemplate >
            <DataTemplate >
               <Button x:Name="btnRemove" Content="X">
                 <Button.Style>
                    <Style TargetType="{x:Type Button}">
                         <Setter Property="FontWeight" Value="ExtraBold" />
                         <Setter Property="FontSize" Value="50" />
                     </Style>
                 </Button.Style>
            </Button>
         </DataTemplate>
   </DataGridTemplateColumn.CellTemplate>
   <DataGridTemplateColumn.CellStyle>
        <Style TargetType="{x:Type DataGridCell}">
               <Setter Property="Background"  Value="Red"/>
               <Setter Property="Visibility" Value="{Binding DataContext.isVisible, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}"/>
        </Style>
   </DataGridTemplateColumn.CellStyle>


1
但是还需要这个(以便标题文本反映可见绑定):` ` - psulek
1
谢谢。@psulek的回复和评论都很有帮助。 - zealoustechie
虽然这个解决方案看起来很棒,但请注意它并没有隐藏列本身,只是它的内容。 - sa.he

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接