我正致力于为我的应用程序开发自定义用户控件。这种控制非常简单。它只是一个网格,[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错误之前失败。
答案 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中创建自定义控件时,有必要探索是否可以使用现有控件并更改其外观以满足您的需要,因为这通常比创建新控件(在翻转它并不总是可以重新利用现有的控件,特别是如果你需要不同的行为)。