【问题标题】:How to correct this sample illustrating WPF DependencyProperty usage?如何更正说明 WPF DependencyProperty 用法的示例?
【发布时间】:2013-04-26 04:44:39
【问题描述】:

我正在尝试运行我附在下面的文章“Dependency Properties in WPF”中的代码。

但应用程序在SetValue(MyDependencyProperty, value); 线上中断,但有例外:

System.Windows.Markup.XamlParseException   
"'' is not a valid value for property 'MyProperty'."

内部异常:

{"'对类型的构造函数的调用 '_3DP_CallBack_DefaultValue.MainWindow' 匹配指定的 绑定约束引发了异常。行号“3”和行 位置‘9’。”}

为了运行这个应用,我应该改变什么?

WPF应用代码:

namespace _3DP_CallBack_DefaultValue
{
  public partial class MainWindow : Window
  {
    public MainWindow()
    {
      InitializeComponent();
      DependencyPropertySample dpSample = new DependencyPropertySample();
      dpSample.MyProperty = "Dependency Property Test";//???

      Binding mybinding = new Binding("MyProperty");
      mybinding.Mode = BindingMode.OneWay;
      mybinding.Source = dpSample;
      BindingOperations.SetBinding(MyTextblock, TextBox.TextProperty, mybinding);
    }
  }
  public class DependencyPropertySample : DependencyObject
  {
    //Register Dependency Property
    public static readonly DependencyProperty MyDependencyProperty 
      = DependencyProperty.Register
           (
               "MyProperty", typeof(string), typeof(DependencyPropertySample), 
               new PropertyMetadata
                 (
                    "Test", 
                    new PropertyChangedCallback(OnMyPropertyChanged), 
                    new CoerceValueCallback(OnCoerceValue)
                 ), 
                 new ValidateValueCallback(OnValidateMyProperty) 
           );

    public string MyProperty
    {
      get
      {
        return (string)GetValue(MyDependencyProperty);
      }
      set
      {
//***************************
//breaking on the following line trying to set any string value   
// in this case "Dependency Property Test"
        SetValue(MyDependencyProperty, value);
      }
    }

    public static void OnMyPropertyChanged(DependencyObject dObject,
          DependencyPropertyChangedEventArgs e)
    {
      MessageBox.Show(e.NewValue.ToString());
    }
    public static string OnCoerceValue(DependencyObject dObject, object val)
    {
      if (val.ToString().CompareTo("Test") == 1)
      {
        return val.ToString();
      }
      return string.Empty;
    }
    public static bool OnValidateMyProperty(object myObj)
    {
      if (myObj.ToString() == string.Empty)
        return false;
      return true;
    }
  }
}

XAML:

<Window x:Class="_3DP_CallBack_DefaultValue.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
        </Grid.RowDefinitions>
        <Label Content="Enter String:" Grid.Row="0"
            VerticalAlignment="Center" />
        <TextBox Text="" Name="MyTextblock" Height="25"
             Width="150" HorizontalAlignment="Right" />
    </Grid>
</Window>

更新:

上面是一个 3d(增量)版本的 WPF 应用程序,带有 2 个以前的 WPF 应用程序,我已经运行没有任何错误

第二个版本有:

  • 完全相同的 XAML 代码
  • 完全相同的C#MainWindow()的构造函数/方法体;
  • class DependencyPropertySample : DependencyObject{} 中缺少的方法
    • OnMyPropertyChanged( DependencyObject dObject, DependencyPropertyChangedEventArgs e)
    • OnValidateMyProperty(object myObj)
    • OnCoerceValue(DependencyObject dObject, object val)

public static readonly DependencyProperty MyDependencyProperty = DependencyProperty.Register() 不同:

这是DependencyPropertySample类的代码来自工作的第二版:

public class DependencyPropertySample : DependencyObject
{
  //Register Dependency Property
  public static readonly DependencyProperty MyDependencyProperty = 
           DependencyProperty.Register
              ("MyProperty", typeof(string), typeof(DependencyPropertySample));
public string MyProperty
{
  get
  {
    return (string)GetValue(MyDependencyProperty);
  }
  set
  {
    SetValue(MyDependencyProperty, value);
  }
}

这是 DependencyPropertySample 类的代码来自失败的 3d 版应用程序

  public class DependencyPropertySample : DependencyObject
  {
    //Register Dependency Property
    public static readonly DependencyProperty MyDependencyProperty 
      = DependencyProperty.Register
           (
               "MyProperty", typeof(string), typeof(DependencyPropertySample), 
               new PropertyMetadata
                 (
                    "Test", 
                    new PropertyChangedCallback(OnMyPropertyChanged), 
                    new CoerceValueCallback(OnCoerceValue)
                 ), 
                 new ValidateValueCallback(OnValidateMyProperty) 
           );

    public string MyProperty
    {
      get
      {
        return (string)GetValue(MyDependencyProperty);
      }
      set
      {
        SetValue(MyDependencyProperty, value);
      }
    }
    public static void OnMyPropertyChanged(DependencyObject dObject,
          DependencyPropertyChangedEventArgs e)
    {
      MessageBox.Show(e.NewValue.ToString());
    }
    public static string OnCoerceValue(DependencyObject dObject, object val)
    {
      if (val.ToString().CompareTo("Test") == 1)
      {
        return val.ToString();
      }
      return string.Empty;
    }
    public static bool OnValidateMyProperty(object myObj)
    {
      if (myObj.ToString() == string.Empty)
        return false;
      return true;
    }
  }

【问题讨论】:

  • 我没有看到您在任何地方指定要绑定的属性。使用 mybinding.Path = "MyProperty"
  • @Erti-ChrisEelmaa, mybinding.Path = "MyPropertyPath"; 给出编译错误"Cannot convert source type 'string' to target type 'System.Windows.PropertyPath'。无论如何,不​​清楚为什么同一应用程序的先前版本没有任何路径设置没有任何问题。请查看我的问题中的更新

标签: c# wpf debugging data-binding dependency-properties


【解决方案1】:
public static string OnCoerceValue(DependencyObject dObject, object val)
    {
      if (val.ToString().CompareTo("Test") == 1)
      {
        return val.ToString();
      }
      **return string.Empty;**
    }

这个函数在比较后返回string.Empty

public static bool OnValidateMyProperty(object myObj)
        {
            if (myObj.ToString() == string.Empty)
                **return false;**
            return true;
        }

然后这个验证返回 false。由于验证失败,您会收到错误消息“'' is not a valid value for property 'MyProperty'。”对这些函数进行适当的更改。

【讨论】:

  • @Manish ,在进行此更改后,DependencyProperty.Register(...) 中的new CoerceValueCallback(OnCoerceValue) 给出编译错误“'OnCoerceValue' 没有重载匹配委托 'System.Windows.CoerceValueCallback'”
  • 如果您只想成功运行此代码,请将 if (val.ToString().CompareTo("Test") == 1) 更改为 if (val.ToString().CompareTo("Test" ) == -1)。即 -1 而不是 1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-16
  • 2015-05-29
  • 1970-01-01
  • 2016-03-03
  • 1970-01-01
  • 1970-01-01
  • 2015-08-02
相关资源
最近更新 更多