WPF列表框中的自定义控件

本文关键字:自定义控件 列表 WPF | 更新日期: 2023-09-27 18:06:59

我已经创建了一些控件,(稍微)扩展了许多ui元素的功能,包括IsError和IsCorrect属性,它们用于向用户表示错误条件。

例如,扩展的复选框。

public class EBC_CheckBox : CheckBox
{
    public static readonly DependencyProperty IsCorrectProperty = DependencyProperty.Register("IsCorrect", typeof(bool), typeof(EBC_CheckBox), new UIPropertyMetadata(false));
    public static readonly DependencyProperty IsErrorProperty = DependencyProperty.Register("IsError", typeof(bool), typeof(EBC_CheckBox), new UIPropertyMetadata(false));
    public EBC_CheckBox() : base()
    {
        IsError = false;
        IsCorrect = false;
    }
    public bool IsError
    {
        get { return (bool)GetValue(IsErrorProperty); }
        set { SetValue(IsErrorProperty, value); }
    }
    public bool IsCorrect
    {
        get { return (bool)GetValue(IsCorrectProperty); }
        set { SetValue(IsCorrectProperty, value); }
    }

在XAML代码中的样式为:

<Style TargetType="{x:Type local:EBC_CheckBox}">
    <Setter Property="Foreground" Value="{StaticResource SBase02}"/>
    <Setter Property="Background" Value="{StaticResource SBase0}"/>
    <Setter Property="FontSize" Value="14"/>
    <Setter Property="VerticalContentAlignment" Value="Center"/>
    <Setter Property="Margin" Value="0,2,8,2"/>
    <Setter Property="BorderBrush" Value="{StaticResource SYellow}"/>
    <Setter Property="BorderThickness" Value="2"/>
    <Style.Triggers>
        <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Foreground" Value="{StaticResource SBase01}"/>
            <Setter Property="BorderThickness" Value="0"/>
        </Trigger>
        <Trigger Property="IsError" Value="True">
            <Setter Property="BorderBrush" Value="{StaticResource SRed}"/>
        </Trigger>
        <Trigger Property="IsCorrect" Value="True">
            <Setter Property="BorderBrush" Value="{StaticResource SGreen}"/>
        </Trigger>
    </Style.Triggers>
</Style>

我的问题是,我想添加一些复选框到一个列表框,在大多数情况下,这是有效的。然而,扩展属性被忽略,看起来ListBox只是将项目作为普通的ui元素呈现,而不是作为扩展版本。

<ListBox  ItemsSource="{Binding MyObjects}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <local:EBC_CheckBox Content="{Binding Path=Name}" IsChecked="{Binding Path=IsPresent}" IsError="{Binding Path=IsError}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

我怎么能得到的对象显示在ListBox内与扩展属性(所以红色时IsError设置等)?

根据Damir的回答,如果我使用数据触发器,我可以设置整个ListBoxItem的样式(即设置边框设置整个项目的边框,而不仅仅是改变复选框的颜色)。

<Style TargetType="{x:Type ListBoxItem}">
    <Style.Triggers>
        <DataTrigger Binding="{Binding IsError}" Value="True">
            <Setter Property="BorderBrush" Value="Red"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

是否有可能这样做并重用控件格式,或者我是否需要创建一个自定义列表框与自定义列表框项?

<Style TargetType="{x:Type ListBoxItem}">
    <Style.Triggers>
        <DataTrigger Binding="{Binding IsError}" Value="True">
            <Setter Property="local:EBC_CheckBox.IsError" Value="True"/>
        </DataTrigger>
    </Style.Triggers>
</Style>
进一步编辑:

我发现下面的代码可以工作,它使用一个固定的项列表:

<ListBox HorizontalAlignment="Left" Height="100" Margin="72,383,0,0" Grid.Row="1" VerticalAlignment="Top" Width="100">
    <local:EBC_CheckBox Content="Item1" IsCorrect="True"/>
    <local:EBC_CheckBox Content="Item2" IsChecked="True"/>
    <local:EBC_CheckBox Content="Item3" IsError="True"/>
    <local:EBC_CheckBox Content="Item4" />
</ListBox>

列表显示项目和他们的视觉状态是根据EBC_CheckBox设置正确处理的。

如果我更改为绑定项的列表,尽管事物的视觉方面没有正确更新- Content和IsChecked字段被正确处理(预期因为它们在基本复选框中,但IsError字段被忽略)

<ListBox Grid.Column="3" Grid.Row="8" HorizontalAlignment="Left" VerticalAlignment="Top" BorderThickness="0"
         ItemsSource="{Binding Things}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <local:EBC_CheckBox Content="{Binding Path=ThingName}" IsChecked="{Binding Path=IsPresent}" IsError="{Binding Path=IsError}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

我错过了什么??

WPF列表框中的自定义控件

解决了这个问题,这一切都归结为构造函数中依赖属性的设置。这些设置不应该在那里,在构造函数中设置它们会覆盖应用程序中的绑定值。

您必须使用DataTrigger而不是简单的Trigger来正确绑定。试试这个:

            <DataTrigger Binding="{Binding IsError}" Value="True">
                <Setter Property="BorderBrush" Value="Red" />
                <Setter Property="FontSize" Value="20"/>
            </DataTrigger>