WPF自定义控件,DependencyProperty的问题 [英] WPF Custom Control, DependencyProperty issue

查看:190
本文介绍了WPF自定义控件,DependencyProperty的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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开始一个新的,因为真正的问题是不是与我原来的职位。 :)

解决方案

您控制未在主窗口的构造函数加载的,所以绑定尚未建立

。您可以检查这通过设置断点的最后一个任务,在更改处理,并在构造函数的结尾。你会看到,构造完成,直到UCTest的属性更改。

您可以通过推迟使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆