C# WPF:带有复选框的自定义ListBoxItem-在复选框上划掉文本

C# WPF:带有复选框的自定义ListBoxItem-在复选框上划掉文本,c#,wpf,datatrigger,listboxitem,C#,Wpf,Datatrigger,Listboxitem,我正在编写一个简单的todo列表,我有一个包含属性“Completed”的类TaskItem,该类在类和所有属性上实现inotifypropertychanged 我想要的是能够设置一个DataTrigger,这样当复选框被选中/取消选中时,文本将被删除 我的列表框代码如下: <ListBox x:Name="TaskListBox" Background="#FF515658" Cursor="Arrow"> <List

我正在编写一个简单的todo列表,我有一个包含属性“Completed”的类TaskItem,该类在类和所有属性上实现inotifypropertychanged

我想要的是能够设置一个DataTrigger,这样当复选框被选中/取消选中时,文本将被删除

我的列表框代码如下:

            <ListBox x:Name="TaskListBox" Background="#FF515658" Cursor="Arrow">
                <ListBox.ItemContainerStyle>
                    <Style TargetType="ListBoxItem">
                        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                        <Setter Property="Focusable" Value="False"/>
                    </Style>
                </ListBox.ItemContainerStyle>
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="Auto"/>
                                </Grid.ColumnDefinitions>
                                <CheckBox Name="CheckBoxZone" Tag="{Binding ID}" IsChecked="{Binding Completed}" Margin="0 0 0 0" Grid.Column="0"/>
                                <TextBlock  x:Name="TaskNameLabel" Text="{Binding Name}" Foreground="White"  Margin="10 -1 0 0" Grid.Column="1"/>
                                <Image x:Name="DelTaskButtom" Margin="8 -1 10 0" Height="10px" Width="10px" Source="../Resources/Delete.png" Cursor="Hand" Grid.Column="2" Visibility="Hidden" PreviewMouseLeftButtonDown="TaskListBoxItem_DeleteTask"/>
                       </Grid>
                            <DataTemplate.Triggers>
                                <DataTrigger Binding="{Binding IsMouseOver,RelativeSource={RelativeSource TemplatedParent}}" Value="True">
                                    <Setter Property="Visibility" TargetName="DelTaskButtom" Value="Visible" />
                                </DataTrigger>


                            <DataTrigger Binding="{Binding IsChecked,RelativeSource={RelativeSource AncestorType={x:Type CheckBox}}}" Value="True">
                                    <Setter Property="TextBlock.TextDecorations" Value="Strikethrough" />
                            </DataTrigger>
                        </DataTemplate.Triggers>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>


有人能帮我吗?我可以通过XAML来完成吗?或者我需要设置事件并通过代码端来完成吗。

您可以将触发器添加到textblock,而不是整个数据模板:

 <TextBlock.Style>
    <Style TargetType="TextBlock">
         <Style.Triggers>
        <!-- Here is how we bind to another control's property -->
        <DataTrigger Binding="{Binding IsChecked, ElementName=CheckBoxZone}" Value="True">
         <Setter Property="TextBlock.TextDecorations" Value="Strikethrough" />
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </TextBlock.Style>


希望有帮助

问题在于触发器中的绑定。不能在DataTemplate触发器中使用相对源。另一个问题是二传手。您必须指定TargetName

有两个选项可以选择如何在DataTemplate中写入触发器:

使用DataTrigger:

<DataTrigger Binding="{Binding Completed}" Value="True">
   <Setter TargetName="TaskNameLabel" Property="TextDecorations" Value="Strikethrough" />
</DataTrigger>

或者使用触发器

<Trigger SourceName="CheckBoxZone" Property="IsChecked" Value="True">       
    <Setter TargetName="TaskNameLabel" Property="TextDecorations" Value="Strikethrough" />
</Trigger>


setter在这两种情况下都是相同的

实际上,这是一种解决方法,即如何在DataTemplate或ControlTemplate之外定义触发器,但这种解决方案不适用于这种情况。在原始代码中,触发器在DataTemplate中的步调正确,但编写得很差。看看我的答案,看看如何修复它。@Liero是的,我承认,但它更干净,更直接!