无法将DataTemplateColumn元素绑定到另一个DataTemplateColumn

时间:2019-05-28 16:59:03

标签: c# wpf data-binding datagrid

我试图通过在同一行中设置另一个元素来在每个DataGrid行中设置一个元素。
如果IsChecked中的ToggleButton为True,则ContentControl中的图像将变为可见。

我已蚕食了example,以使其正常工作。 This这个例子似乎也很相似,希望我不要重复任何事情。

这是我实现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 个答案:

答案 0 :(得分:1)

第一件事:您永远都不要这样做。 XAML非常灵活,可以使您做一些非常聪明的事情,但是仅仅因为您做不到就意味着您应该做。在这种情况下,正确的解决方案是为每个行元素创建一个具有布尔属性的视图模型,按钮和数据触发器都可以绑定到该布尔属性。除了更加灵活之外,测试,调试和记录等也更加容易。

也就是说,您的要求在技术上是可能的。由于数据网格采用了各种优化措施,因此它们实际上非常复杂,因此您仍然需要使用中间属性,但是由于您不想使用视图模型,因此必须在数据网格中使用Tag属性。按钮的DataGridCell代替(可用于任意用户数据):

  1. 绑定按钮的IsChecked属性以对其父DataGridCell的Tag属性进行单向源绑定。
  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>

但是认真的...只要使用视图模型即可。