WPF 4 DataGrid:显示和隐藏列

Gre*_*ora 9 wpf xaml wpfdatagrid

我正在尝试为DataGrid实现列选择器功能,如果我尝试将列的标题内容定义为不仅仅是一个字符串,那么我遇到了问题.下面是一个非常简化的示例,其中所有样式,视图模型,绑定等都被剥离.

共有3列:

第一列使用标题字符串.第二列尝试使用工具提示将标题内容设置为Label.第三列绑定使用ToolTip将标题内容设置为TextBlock.

单击列A的"切换可见性"按钮可以正常工作.列B和C的"切换可见性"按钮会导致InvalidOperationException,并显示消息"指定的元素已经是另一个元素的逻辑子元素.首先断开它".

<Window x:Class="DataGridColumnChoosing.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <StackPanel Orientation="Horizontal" Margin="0,10">
        <TextBlock Margin="15, 0">Toggle Visibility:</TextBlock>
        <Button Click="ToggleA">Column A</Button>
        <Button Click="ToggleB">Column B</Button>
        <Button Click="ToggleC">Column C</Button>
    </StackPanel>
    <!-- Main Fuel Mileage Datagrid -->
    <DataGrid  x:Name="mySampleDataGrid" Grid.Row="1"
                    AutoGenerateColumns="False" CanUserSortColumns="False" CanUserResizeRows="False" CanUserAddRows="False"
                    GridLinesVisibility="All" RowHeaderWidth="0">
        <DataGrid.Columns>
            <DataGridTemplateColumn x:Name="colA" Width="40*" IsReadOnly="True" Header="Column A">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>


            <DataGridTemplateColumn x:Name="colB" Width="40*" IsReadOnly="True" >
                <DataGridTemplateColumn.Header>
                    <Label Content="Column B" ToolTip="A short explanation of Column B"/>
                </DataGridTemplateColumn.Header>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

            <DataGridTemplateColumn x:Name="colC" Width="40*" IsReadOnly="True" >
                <DataGridTemplateColumn.Header>
                    <TextBlock Text="Column C" ToolTip="A short explanation of Column C " />
                </DataGridTemplateColumn.Header>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock  />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>
Run Code Online (Sandbox Code Playgroud)

在此示例中切换可见性的按钮的简单单击事件处理程序只是修改列的可见性.

    private void ToggleA(object sender, RoutedEventArgs e)
    {
        colA.Visibility = colA.Visibility == System.Windows.Visibility.Visible ? System.Windows.Visibility.Hidden : System.Windows.Visibility.Visible;
    }

    private void ToggleB(object sender, RoutedEventArgs e)
    {
        colB.Visibility = colB.Visibility == System.Windows.Visibility.Visible ? System.Windows.Visibility.Hidden : System.Windows.Visibility.Visible;
    }

    private void ToggleC(object sender, RoutedEventArgs e)
    {
        colC.Visibility = colC.Visibility == System.Windows.Visibility.Visible ? System.Windows.Visibility.Hidden : System.Windows.Visibility.Visible;
    }
Run Code Online (Sandbox Code Playgroud)

谢谢大家.

Rac*_*hel 11

当我在我的资源中定义了一个控件并试图在多个控件的内容区域中使用它时,我遇到过这个问题.这不起作用,因为控件只能属于一个父级.

相反,我需要定义一个包含我想要的控件的模板,并直接设置我的对象的模板而不是内容.

你对@Gimno的答案的评论让我觉得情况就是如此.

尝试更改它,而不是直接在DataGrid.Header的内容中设置Label/TextBox,将DataGrid.HeaderTemplate设置为包含Label或TextBox的DataTemplate.

编辑

这是一些示例代码

<DataGridTemplateColumn x:Name="colB" Width="40*" IsReadOnly="True" >
    <DataGridTemplateColumn.HeaderTemplate>
        <DataTemplate>
            <Label Content="Column B" ToolTip="A short explanation of Column B"/>
        </DataTemplate>
    </DataGridTemplateColumn.HeaderTemplate>
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Run Code Online (Sandbox Code Playgroud)