在ItemsControl中显示自定义项目 [英] Displaying customised Item in ItemsControl

查看:67
本文介绍了在ItemsControl中显示自定义项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个(略微)扩展的Checkbox,该复选框具有IsError属性(主要用于在不满足某些条件时将复选框的颜色更改为红色),如下所示:

I have created a (slightly) extended Checkbox that has an IsError property (basically used to change the colour of the checkbox to red when some condition is not met) as follows:

public class MyCheckBox : CheckBox
{
    public static readonly DependencyProperty IsErrorProperty = DependencyProperty.Register("IsError", typeof(bool), typeof(MyCheckBox), new UIPropertyMetadata(false));

    public MyCheckBox() : base()
    {
        IsError = false;
        IsCorrect = false;
    }

    public bool IsError
    {
        get { return (bool)GetValue(IsErrorProperty); }
        set { SetValue(IsErrorProperty, value); }
    }
}

此控件与以下样式相关联:

This control is associated with the following style:

<Style TargetType="{x:Type local:MyCheckBox}">
    <Setter Property="FontSize" Value="14"/>
    <Setter Property="VerticalContentAlignment" Value="Center"/>
    <Setter Property="Margin" Value="0,2,8,2"/>
    <Setter Property="BorderBrush" Value="Yellow"/>
    <Setter Property="BorderThickness" Value="2"/>
    <Style.Triggers>
        <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Foreground" Value="LightGray"/>
            <Setter Property="BorderThickness" Value="0"/>
        </Trigger>
        <Trigger Property="IsError" Value="True">
            <Setter Property="BorderBrush" Value="Red"/>
        </Trigger>
    </Style.Triggers>
</Style>

一切正常,如果我创建这些复选框之一,它将正确响应IsError绑定.

All is well, if I create one of these checkboxes the it responds to the IsError binding correctly.

我遇到的问题是将它们放在ItemsControl中时.如果我创建一个非常基本的项目控件并手动设置值,则它会起作用-显示项目列表,并且IsError和IsChecked属性将按预期运行.

The issue I'm having is when placing these inside an ItemsControl. If I create a very basic items control and set the values manually then it works - the list of items is displayed and the IsError and IsChecked properties act as expected.

<ItemsControl Grid.Column="3" Grid.Row="8" HorizontalAlignment="Left" VerticalAlignment="Top" BorderThickness="0">
    <local:MyCheckBox Content="Item1"/>
    <local:MyCheckBox Content="Item2" IsChecked="True"/>
    <local:MyCheckBox Content="Item3" IsError="True"/>
    <local:MyCheckBox Content="Item4" IsChecked="True" IsError="True"/>
</ItemsControl>

但是,如果我对项目列表使用绑定,那么Content和IsChecked属性将按预期方式工作,但是IsError属性将被完全忽略,那么我将边框变为红色.

If, however I use binding for the list of items then the Content and IsChecked properties work as expected, but the IsError property is completely ignored, I cannot get the border to change to red.

<ItemsControl Grid.Column="3" Grid.Row="8" HorizontalAlignment="Left" VerticalAlignment="Top" BorderThickness="0">
              ItemsSource="{Binding MyThings}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <local:MyCheckBox Content="{Binding Path=ColorName}" IsChecked="{Binding Path=IsPresent}" IsError="{Binding Path=IsError}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

我知道IsError绑定值是正确的(我通过包含与显示正确的True/False信息的相同值绑定的Label进行测试),但是我无法解决如何使自定义Checkbox正确显示的问题;好像显示的项目使用的是标准复选框,而不是自定义版本.

I know that the IsError binding value is correct (I tested by including a Label bound to the same value which displayed the correct True/False information) but I cannot work out how to get the customised Checkbox to display properly; it's as if the displayed item is using a standard Checkbox instead of the customised version.

作为参考,控件绑定到的项目列表如下:

For reference, the list of items the control is bound to is as follows:

public class Thing : INotifyPropertyChanged
{
    #region INotifyPropertyChanged
    protected void RaisePropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;

        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    #endregion

    private string colorName;
    public string ColorName 
    {
        get { return colorName; }
        set { colorName = value; RaisePropertyChanged("ColorName"); } 
    }

    private bool isPresent;
    public bool IsPresent
    {
        get { return isPresent; }
        set { isPresent = value; RaisePropertyChanged("IsPresent"); }
    }

    private bool isError;
    public bool IsError
    {
        get { return isError; }
        set { isError = value; RaisePropertyChanged("IsError"); } 
    }

    public CastorClip(string colorName)
    {
        ColorName = colorName;
        IsPresent = false;
        IsError = false;
    }
}

private ObservableCollection<Thing> myThings = new ObservableCollection<Thing>();
public ObservableCollection<Thing> MyThings
{
    get { return myThings; }
    set { myThings = value; RaisePropertyChanged("MyThings"); }
}

我想念什么?我该如何进行这项工作?

What am I missing? How can I make this work?

推荐答案

事实证明,这是自定义复选框的构造函数中的一个问题,在该复选框中,设置了IsError属性以覆盖绑定表达式.我也会在这里允许其他可能性,以便确实进入WPF这些常见陷阱的其他人可以立即检查它们.

It turns out it was a problem in the constructor of the custom checkbox where the IsError property was being set overwriting the binding expression. I'll let the other possibilities here also so that other people that did get into these common traps of WPF can check them right away.

默认情况下,属性IsError不绑定两种方式,请更改:

The property IsError is not bound two way by default, change the:

new UIPropertyMetadata(false)

收件人:

new FrameworkPropertyMetadata {
    BindsTwoWayByDefault = true,
    DefaultValue = false
}

此外,将其添加到您的复选框的静态构造函数中,以便它将寻求特定于您的复选框的默认样式:

Also, add this to the static constructor of your checkbox so that it will seek a default style specific to your checkbox:

static MyCheckBox ()
{
    DefaultStyleKeyProperty.OverrideMetadata (typeof (MyCheckBox), new FrameworkPropertyMetadata (typeof (MyCheckBox)));
}

请确保检查如何将资源添加到您的应用.

Be sure to check how the resource is being added to your app.

这篇关于在ItemsControl中显示自定义项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆