WPF UserControl公开子控件的绑定属性

时间:2015-02-02 16:26:18

标签: c# wpf xaml binding user-controls

我正致力于为我的应用程序开发自定义用户控件。这种控制非常简单。它只是一个网格,[0,0]中有一个复选框,[0,1]中有一个TextBlock。我在XAML中设计的方式没有任何问题。

然而,第二步是给我一些麻烦。我试图揭露IsChecked bool?我的子控件是一个Checkbox,用于绑定我的mainform,以及与TextBlock的Text属性相同的想法。

我尝试了几种不同的方法,但无济于事。

这是我的通用代码:

public partial class CDCheckBox : UserControl
{
    public bool? IsChecked
    {
        get { return chk.IsChecked; }
        set { chk.IsChecked = value; }
    }

    public string Text
    {
        get { return lbl.Text; }
        set { lbl.Text = value; }
    }

    public static readonly DependencyProperty IsCheckedProperty =
    DependencyProperty.Register(
        "IsChecked",
        typeof(bool?),
        typeof(CDCheckBox),
        new PropertyMetadata(default(bool?), OnItemsPropertyChanged));

    public static readonly DependencyProperty TextProperty =
    DependencyProperty.Register(
        "Text",
        typeof(string),
        typeof(CDCheckBox),
        new PropertyMetadata(default(string), OnItemsPropertyChanged));

    /*
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnNotify(string propName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }
    */
    private static void OnItemsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        // AutocompleteTextBox source = d as AutocompleteTextBox;
        // Do something...
        //lbl.Text = e.NewValue.ToString();
    }

    /*
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnNotify(string propName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }
    */

    public CDCheckBox()
    {
        InitializeComponent();
    }
}

当我运行上面的代码时,我没有收到任何错误,但我的绑定数据并没有显示在我的TextBlock控件中。当我在编写dependnency属性之前尝试过时,它在我的XAML中给出了一个错误,即" A' Binding'不能设置为'IsChecked'类型' CDCheckBox'的属性。 A'绑定'只能在DependencyObject的DependencyProperty上设置。"

有趣的是,这个错误并没有出现在构造函数中,而是出现在window_loaded方法中。这似乎是一个红色的鲱鱼,但是,好像我注释掉了该代码,它仍然在表单可以显示XAMLParse错误之前失败。

1 个答案:

答案 0 :(得分:1)

根据我的评论,您可以尝试设置具有所需属性类型的现有控件的样式。例如,在自定义控件中,您具有可为空的布尔属性和字符串属性。如果您重新使用CheckBox控件,它已经有一个可以为空的布尔属性(IsChecked)和一个对象属性(Content),它可用于保存字符串。

以下是您如何重新设置CheckBox控件并更改其模板以获得您所追求的结果:

<Window x:Class="..."
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Window.Resources>
        <Style x:Key="MySuperCheckboxStyle"
               TargetType="{x:Type CheckBox}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type CheckBox}">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition />
                                <ColumnDefinition />
                            </Grid.ColumnDefinitions>
                            <CheckBox Grid.Column="0"
                                      IsChecked="{TemplateBinding IsChecked}"
                                      Content="Whatever you need here" />
                            <TextBlock Grid.Column="1"
                                       Text="{TemplateBinding Content}" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>

    <StackPanel>
        <CheckBox IsChecked="True"
                  Content="Unstyled check box"
                  Margin="10" />
        <CheckBox Style="{StaticResource MySuperCheckboxStyle}"
                  IsChecked="True"
                  Content="Styled check box"
                  Margin="10" />
    </StackPanel>
</Window>

这里的关键是控件模板中使用的TemplateBinding绑定。它们不会绑定到正常数据绑定中的数据上下文,而是绑定到模板控件的属性。

每当您发现自己想要在WPF中创建自定义控件时,有必要探索是否可以使用现有控件并更改其外观以满足您的需要,因为这通常比创建新控件(在翻转它并不总是可以重新利用现有的控件,特别是如果你需要不同的行为)。