带有依赖属性和子控件的用户控件
本文关键字:控件 用户 依赖 属性 | 更新日期: 2023-09-27 18:18:07
我试图在WPF中创建我自己的,非常简单的Usercontrol。它基本上只是一个组合框,里面有一些额外的逻辑。我尝试使用本教程创建自己的依赖属性:http://www.codeproject.com/Articles/140620/WPF-Tutorial-Dependency-Property
到目前为止,这工作得很好,但如果属性发生变化,我也想在用户控件中的组合框上反映这一点。似乎我不能直接将子控件绑定到我的新Dependency-Project。
我的代码现在看起来是这样的:
public partial class ClassSelector : UserControl
{
public static readonly DependencyProperty CurrentValueProperty =
DependencyProperty.Register("CurrentValue", typeof(ClassType),
typeof(ClassSelector), new FrameworkPropertyMetadata());
public ClassType CurrentValue
{
get
{
return (ClassType)this.GetValue(CurrentValueProperty);
}
set
{
this.SetValue(CurrentValueProperty, value);
}
}
public ClassSelector()
{
this.DataContext = this;
InitializeComponent();
cmbClassType.ItemsSource = Enum.GetValues(typeof(ClassType));
}
}
设置依赖属性或组合框的值对我来说似乎很奇怪。我尝试通过:
在xaml中直接绑定它<Grid>
<ComboBox x:Name="cmbClassType" SelectedItem="{Binding Path=CurrentValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectionChanged="cmbClassType_SelectionChanged" />
</Grid>
我尝试将dependency - project changed Event映射到组合框,反之亦然,但是这会导致非常奇怪的代码,因为组合框的更改必须更改组合框的属性值和属性值。
我很确定有可能绑定一个DependencyProperty到子控件,但我找不到一种方法来使这个工作。
提前感谢大家的建议,祝周末愉快
马提亚
Edith说:调用窗口需要将对象绑定到网格上,而不是绑定到窗口上,所以例如:
grdMain.DataContext = new DeckSearch();
工作正常,同时
this.DataContext = new DeckSearch();
此行为仅在我的自定义控件,所有其他控件与窗口本身的DataContext一起工作得很好。
好了,这里我修复了你的代码,它在我的末端工作了
UserControlCodeBehind
public partial class ClassSelector : UserControl
{
public static readonly DependencyProperty CurrentValueProperty = DependencyProperty.Register("CurrentValue", typeof(ClassType),
typeof(ClassSelector), new FrameworkPropertyMetadata()
{
DefaultValue = ClassType.Type1,
BindsTwoWayByDefault = true,
PropertyChangedCallback = CurrentValueChanged,
DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
});
private static void CurrentValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var obj = (ClassSelector)d;
obj.cmbClassType.SelectedValue = e.NewValue;
}
public ClassType CurrentValue
{
get
{
return (ClassType)this.GetValue(CurrentValueProperty);
}
set
{
this.SetValue(CurrentValueProperty, value);
}
}
public ClassSelector()
{
InitializeComponent();
cmbClassType.ItemsSource = Enum.GetValues(typeof(ClassType));
cmbClassType.SelectedValue = CurrentValue;
}
}
UserControl的Xaml部分
<Grid>
<ComboBox x:Name="cmbClassType" SelectedValue="{Binding Path=CurrentValue}"/>
</Grid>
请检查您的终端是否正常工作。我没有添加任何额外的代码检查线程安全性和所有。
编辑
在我的解决方案中,当CurrentValue
变化时,我确实得到了Class
Property
通知。
下面是我的示例MainWindow代码。
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
Task.Run(() =>
{
Thread.Sleep(1000);
Dispatcher.InvokeAsync(() =>
{
customCombobox.CurrentValue = ClassType.Type3;//Updating the UserControl DP
});
Thread.Sleep(2000);
this.CurrentValue = ClassType.Type2;//Updating my local Property
});
}
private ClassType _currentValue;
public ClassType CurrentValue
{
get { return _currentValue; }
set
{
_currentValue = value;
Debug.WriteLine("Value Changed to " + value.ToString());
RaisePropertyChanged("CurrentValue");
}
}
public event PropertyChangedEventHandler PropertyChanged;
void RaisePropertyChanged(string propName)
{
var pc = PropertyChanged;
if (pc != null)
pc(this, new PropertyChangedEventArgs(propName));
}
}
和mainwindow。xaml
<Window x:Class="WpfApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication"
Title="MainWindow" Height="250" Width="525">
<local:ClassSelector x:Name="customCombobox" Height="25" CurrentValue="{Binding CurrentValue}"/>
</Window>