WPF 4 DataGrid: отображение и скрытие столбцов - PullRequest
9 голосов
/ 18 марта 2011

Я пытаюсь реализовать функцию выбора столбца для DataGrid, и у меня возникают проблемы, если я пытаюсь определить содержимое заголовка для столбца как нечто большее, чем просто строка.Ниже приведен очень упрощенный пример со всеми стилями, моделями представления, привязкой и т. Д.

Есть 3 столбца:

Первый столбец использует строку для заголовка.Во втором столбце делается попытка установить заголовок с меткой с помощью всплывающей подсказки.Третий столбец связан с установкой содержимого заголовка в TextBlock с помощью всплывающей подсказки.

Щелчок по кнопке Toggle Visibility для столбца 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>

Простойобработчики событий click для кнопок, которые переключают видимость в этом примере, просто изменяют видимость столбцов.

    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;
    }

Спасибо всем.

Ответы [ 2 ]

11 голосов
/ 18 марта 2011

Однажды у меня возникла эта проблема, когда я определил элемент управления в своих ресурсах и пытался использовать его в нескольких областях содержимого элемента управления. Это не работает, потому что элемент управления может принадлежать только одному родителю.

Вместо этого мне нужно было определить какой-то шаблон, содержащий требуемый элемент управления, и установить шаблон моего объекта вместо содержимого напрямую.

Ваш комментарий к ответу @ Gimno заставляет меня думать, что это так.

Попробуйте изменить его, чтобы вместо установки Label / TextBox в содержимом DataGrid.Header напрямую, установите DataGrid.HeaderTemplate на DataTemplate, который содержит Label или TextBox.

EDIT

Вот пример кода

<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>
2 голосов
/ 18 марта 2011

Думаю, было бы проще, если бы вы просто использовали DataGridTemplateColumn.HeaderStyle вместо DataGridTemplateColumn.Header

Как пример для столбца c:

<DataGridTemplateColumn x:Name="colC" Width="40*" IsReadOnly="True" >
    <DataGridTemplateColumn.HeaderStyle>
        <Style TargetType="DataGridColumnHeader">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <TextBlock Text="Column C"  ToolTip="A short explanation of Column C "/>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </DataGridTemplateColumn.HeaderStyle>
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock  />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
  </DataGridTemplateColumn>
</DataGridTemplateColumn.HeaderStyle>
...