WPF Custom Control, DependencyProperty issue

妖精的绣舞 提交于 2019-12-12 09:23:29

问题


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. : )


回答1:


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);


来源:https://stackoverflow.com/questions/6639237/wpf-custom-control-dependencyproperty-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!