WPF自定义控件,DependencyProperty的问题 [英] WPF Custom Control, DependencyProperty issue
问题描述
Ive得到的自定义控件测试code设置:
///<总结>
///为UCTest.xaml交互逻辑
///< /总结>
公共部分类UCTest:用户控件
{
公共静态只读的DependencyProperty LastNameProperty =
DependencyProperty.Register(姓氏的typeof(串)的typeof(UCTest)
新PropertyMetadata(NO NAME,LastNameChangedCallback,LastNameCoerceCallback)
LastNameValidateCallback);
私有静态无效LastNameChangedCallback(
DependencyObject的OBJ,DependencyPropertyChangedEventArgs E)
{
Console.WriteLine(e.OldValue ++ e.NewValue);
}
私有静态对象LastNameCoerceCallback(DependencyObject的OBJ,对象o)
{
字符串s = O为串;
如果(s.Length→8)
S = s.Substring(0,8);
返回S;
}
私有静态布尔LastNameValidateCallback(对象的值)
{
返回值!= NULL;
}
公共字符串名字
{
得到
{
返回(串)的GetValue(LastNameProperty);
}
组
{
的SetValue(LastNameProperty,价值);
}
}
公共UCTest()
{
的InitializeComponent();
}
}
在XAML code没什么特别的:
<用户控件...>
<电网的DataContext ={结合}>
< /网格>
< /用户控件>
code。在我看来,型号:
公共类视图模型:DependencyObject的
{
公共静态只读的DependencyProperty LastNameProperty =
DependencyProperty.Register(姓氏的typeof(串)的typeof(视图模型));
公共字符串名字
{
得到
{
返回(串)的GetValue(LastNameProperty);
}
组
{
的SetValue(LastNameProperty,价值);
}
}
}
code在MainWondow.XAML.cs:
公共主窗口()
{
的InitializeComponent();
VAR视图模型=新视图模型();
的DataContext =视图模型;
viewModel.LastName =ASDF;
viewModel.LastName =56udfh;
viewModel.LastName =09ualkja;
}
MainWindow.XAML code:
<窗口...>
<电网>
< CustomControlTest:UCTest姓氏={结合姓氏}/>
< /网格>
< /窗>
Ive得到了断点设置,并设置为当打。输出(下)表明,物业只能调用更新的姓氏最后一次执行。我希望它被调用上改变了每一个执行...任何想法,为什么?
步骤为:步进比非用户code'CustomControlTest.App.App
步骤为:步进比非用户code'CustomControlTest.App.InitializeComponent
功能:CustomControlTest.UCTest.LastNameValidateCallback(对象),主题:0x1DDC主线程
功能:CustomControlTest.UCTest.LastNameValidateCallback(对象),主题:0x1DDC主线程
功能:CustomControlTest.UCTest.LastNameValidateCallback(对象),主题:0x1DDC主线程
功能:CustomControlTest.UCTest.LastNameCoerceCallback(System.Windows.DependencyObject,对象),主题:0x1DDC主线程
功能:CustomControlTest.UCTest.LastNameValidateCallback(对象),主题:0x1DDC主线程
功能:CustomControlTest.UCTest.LastNameValidateCallback(对象),主题:0x1DDC主线程
功能:CustomControlTest.UCTest.LastNameCoerceCallback(System.Windows.DependencyObject,对象),主题:0x1DDC主线程
功能:CustomControlTest.UCTest.LastNameChangedCallback(System.Windows.DependencyObject,System.Windows.DependencyPropertyChangedEventArgs),主题:0x1DDC主线程
无名09ualkja
谢谢
PS,这是一个后续问题我p revious交一>。认为Id开始一个新的,因为真正的问题是不是与我原来的职位。 :)
解决方案您控制未在主窗口的构造函数加载的,所以绑定尚未建立
您可以通过推迟使用Dispatcher分配解决这个问题:
this.Dispatcher.BeginInvoke((行动)(()=>
{
viewModel.LastName =ASDF;
viewModel.LastName =56udfh;
viewModel.LastName =09ualkja;
}),
DispatcherPriority.DataBind);
Ive got a test code setup with the custom control:
/// <summary>
/// Interaction logic for UCTest.xaml
/// </summary>
public partial class UCTest : UserControl
{
public static readonly DependencyProperty LastNameProperty =
DependencyProperty.Register("LastName", typeof(string), typeof(UCTest),
new PropertyMetadata("No Name", LastNameChangedCallback, LastNameCoerceCallback),
LastNameValidateCallback);
private static void LastNameChangedCallback(
DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
Console.WriteLine(e.OldValue + " " + e.NewValue);
}
private static object LastNameCoerceCallback(DependencyObject obj, object o)
{
string s = o as string;
if (s.Length > 8)
s = s.Substring(0, 8);
return s;
}
private static bool LastNameValidateCallback(object value)
{
return value != null;
}
public string LastName
{
get
{
return (string)GetValue(LastNameProperty);
}
set
{
SetValue(LastNameProperty, value);
}
}
public UCTest()
{
InitializeComponent();
}
}
Nothing fancy in the XAML code:
<UserControl ...>
<Grid DataContext="{Binding}">
</Grid>
</UserControl>
Code in my View-Model:
public class ViewModel : DependencyObject
{
public static readonly DependencyProperty LastNameProperty =
DependencyProperty.Register("LastName", typeof(string), typeof(ViewModel));
public string LastName
{
get
{
return (string)GetValue(LastNameProperty);
}
set
{
SetValue(LastNameProperty, value);
}
}
}
Code in MainWondow.XAML.cs:
public MainWindow()
{
InitializeComponent();
var viewModel = new ViewModel();
DataContext = viewModel;
viewModel.LastName = "asdf";
viewModel.LastName = "56udfh";
viewModel.LastName = "09ualkja";
}
MainWindow.XAML code:
<Window...>
<Grid>
<CustomControlTest:UCTest LastName="{Binding LastName}"/>
</Grid>
</Window>
Ive got breakpoints setup and set to "When Hit". Output (below) shows that property only called to be updated on the last execution of "LastName". I would expect it to be calling the on changed on every execute... Any ideas why?
Step into: Stepping over non-user code 'CustomControlTest.App.App'
Step into: Stepping over non-user code 'CustomControlTest.App.InitializeComponent'
Function: CustomControlTest.UCTest.LastNameValidateCallback(object), Thread: 0x1DDC Main Thread
Function: CustomControlTest.UCTest.LastNameValidateCallback(object), Thread: 0x1DDC Main Thread
Function: CustomControlTest.UCTest.LastNameValidateCallback(object), Thread: 0x1DDC Main Thread
Function: CustomControlTest.UCTest.LastNameCoerceCallback(System.Windows.DependencyObject, object), Thread: 0x1DDC Main Thread
Function: CustomControlTest.UCTest.LastNameValidateCallback(object), Thread: 0x1DDC Main Thread
Function: CustomControlTest.UCTest.LastNameValidateCallback(object), Thread: 0x1DDC Main Thread
Function: CustomControlTest.UCTest.LastNameCoerceCallback(System.Windows.DependencyObject, object), Thread: 0x1DDC Main Thread
Function: CustomControlTest.UCTest.LastNameChangedCallback(System.Windows.DependencyObject, System.Windows.DependencyPropertyChangedEventArgs), Thread: 0x1DDC Main Thread
No Name 09ualkja
Thanks,
PS, this is a follow up question to my previous post. Thought Id start a new one because the real issue is not related to my original post. : )
Your control is not loaded in the MainWindow constructor, so the Binding is not established yet. You may check this by setting breakpoint on the last assignment, in the change handler, and at the end of constructor. You'll see that constructor finishes until UCTest's property changes.
You can solve this problem by deferring assignments using Dispatcher:
this.Dispatcher.BeginInvoke((Action)(() =>
{
viewModel.LastName = "asdf";
viewModel.LastName = "56udfh";
viewModel.LastName = "09ualkja";
}),
DispatcherPriority.DataBind);
这篇关于WPF自定义控件,DependencyProperty的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!