[英]WPF UserControl exposing properties of subcontrols for binding
我正在为我的应用程序开发自定义用户控件。 此控件非常简单。 它只是一个网格,在[0,0]中有一个复选框,在[0,1]中有一个TextBlock。 我对它在XAML中的设计方式没有任何疑问。
但是,第二步给我带来了一些麻烦。 我正在尝试公开IsChecked布尔值? 子控件的一部分,该复选框是用于绑定到我的主窗体上的复选框,并且具有与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控件中。 在编写依赖项属性之前进行尝试时,它在XAML中给我一个错误,提示“无法在类型'CDCheckBox'的'IsChecked'属性上设置'Binding'。只能在DependencyProperty上设置'Binding' DependencyObject。”
但是有趣的是,此错误并未出现在构造函数中,而是出现在我编写的window_loaded方法中。 但是,这似乎是一条红色的鲱鱼,就像我注释掉该代码一样,它仍然无法通过表格显示XAMLParse错误。
根据我的评论,您可以尝试设计具有所需属性类型的现有控件的样式。 例如,在自定义控件中,您具有可为null的布尔属性和字符串属性。 如果重新使用CheckBox
控件,则该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中创建自定义控件时,就值得探索一下是否可以采用现有控件并更改其外观以适合您的需要,因为这通常比创建新控件要少(反之,则不是总是有可能重新利用现有控件的用途,尤其是在您需要其他行为的情况下。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.