Невозможно привязать элемент DataTemplateColumn к другому DataTemplateColumn - PullRequest
1 голос
/ 28 мая 2019

Я пытаюсь установить элемент в каждой строке DataGrid, установив другой элемент в той же строке.
Если IsChecked из ToggleButton равно True, изображение в ContentControl станет видимым.

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

Это фрагмент кода из моей реализации DataGrid:

<Grid>
    <StackPanel>
        <Grid Margin="0" Grid.Column="0" Grid.Row="3">
            <DataGrid 
              ItemsSource="{Binding Path=. , Mode=OneWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}"   
              AutoGenerateColumns="False" 
              Height="Auto" 
              HorizontalAlignment="Left"               
              VerticalAlignment="Top" 
              ScrollViewer.CanContentScroll="True" 
              ScrollViewer.VerticalScrollBarVisibility="Visible"
              x:Name="Filter_grid"  
              Grid.Row="1">
                <DataGrid.Columns >
                    <DataGridTextColumn Header="CAN ID"  Binding="{Binding Information.CAN_ID}" Width="50" />
                    <DataGridTextColumn Header="Messagen Name" Binding="{Binding Information.CAN_ID_description}" Width="300" />
                    <DataGridTextColumn Binding="{Binding Information.Status}" Width="50" />
                    <DataGridTemplateColumn Header = "Filter ON" Width="SizeToCells" IsReadOnly="True">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <ContentControl Content="{Binding Information.Tick}">
                                    <ContentControl.Style>
                                        <Style TargetType = "ContentControl" >
                                            <Setter Property="Visibility" Value="Hidden"/>
                                            <Style.Triggers>                                                   
                                                <DataTrigger  Binding = "{Binding  Path=IsChecked, ElementName=Filter_on}" Value="True">
                                                    <Setter Property = "Visibility" Value="Visible"/>
                                                </DataTrigger>
                                            </Style.Triggers>
                                        </Style>
                                    </ContentControl.Style>
                                </ContentControl>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <DataGridTemplateColumn x:Name="F_column" Header ="Select">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <ToggleButton  x:Name="Filter_on" Content="Switch" />                                                                   
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>             
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </StackPanel>
</Grid>

Я не могу получить ElementName, найти ToggleBox и получить Cannot find source for binding with reference 'ElementName=Filter_on'.

Я пытался сделать то же самое с

<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridTemplateColumn}}, Path=F_column.Filter_on}" Value="True">, или используя x:Reference, что вызывает у меня исключение, которое я не могу расшифровать.

1 Ответ

1 голос
/ 29 мая 2019

Перво-наперво: никогда не делай этого. XAML очень гибок и позволяет вам делать очень умные вещи, но только потому, что вы можете, не означает, что вы должны это делать. Правильным решением в этом случае является создание модели представления для каждого элемента строки с логическим свойством, с которым может быть связана кнопка и ваш триггер данных. Помимо большей гибкости, также гораздо проще тестировать, отлаживать, регистрировать и т. Д.

Тем не менее, то, что вы спрашиваете, технически возможно. DataGrids на самом деле довольно сложны из-за различных оптимизаций, которые они используют и т. Д., Поэтому вам все равно нужно использовать промежуточное свойство, но, поскольку вы не хотите использовать модель представления, вам придется использовать свойство Tag в DataGridCell кнопки. вместо этого (который может использоваться для произвольных пользовательских данных):

  1. Свяжите свойство кнопки IsChecked, чтобы сделать одностороннюю привязку к источнику Tag родительского свойства DataGridCell.
  2. Свяжите DataTrigger, чтобы найти родителя DataGridCellsPanel, а затем привяжите напрямую к свойству Tag соответствующего дочернего элемента, т.е. Children[1].Tag.

Соедините это, и вы получите это:

<DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False">
    <DataGrid.Columns>

        <DataGridTemplateColumn Header = "Filter ON" Width="SizeToCells" IsReadOnly="True">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ContentControl>
                        <ContentControl.Style>
                            <Style TargetType = "ContentControl" >
                                <Setter Property="Visibility" Value="Hidden"/>
                                <Style.Triggers>
                                    <DataTrigger  Binding = "{Binding Path=Children[1].Tag, RelativeSource={RelativeSource AncestorType={x:Type DataGridCellsPanel}}}" Value="True">
                                        <Setter Property = "Visibility" Value="Visible"/>
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </ContentControl.Style>
                        <TextBlock Text="Content goes here" />
                    </ContentControl>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>


        <DataGridTemplateColumn x:Name="F_column" Header ="Select">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ToggleButton x:Name="Filter_on" Content="Switch" IsChecked="{Binding Path=Tag, RelativeSource={RelativeSource AncestorType=DataGridCell}, Mode=OneWayToSource}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>

    </DataGrid.Columns>

</DataGrid>

А если серьезно ... просто используйте модель представления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...