【问题标题】:Dependency Property in F# Default Value does not matchF# 默认值中的依赖属性不匹配
【发布时间】:2015-05-16 16:45:26
【问题描述】:

我正在尝试将限制输入到 ComboBox 中的文本的最大长度的 C# 依赖属性转换为 F#。该程序是一个 MVVM 程序,模型和视图模型使用 F#,视图使用 C#。工作 C# 代码是这样的:

public class myComboBoxProperties
    {
        public static int GetMaxLength(DependencyObject obj)
        {
            return (int)obj.GetValue(MaxLengthProperty);
        }

        public static void SetMaxLength(DependencyObject obj, int value)
        {
            obj.SetValue(MaxLengthProperty, value);
        }

        // Using a DependencyProperty as the backing store for MaxLength. This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MaxLengthProperty =
            DependencyProperty.RegisterAttached("MaxLength",
            typeof(int),
            typeof(myComboBoxProperties),
            new UIPropertyMetadata(OnMaxLengthChanged));

        private static void OnMaxLengthChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            if (obj is ComboBox)
            {
                ComboBox comboBox = (ComboBox)obj;

                comboBox.Loaded += (sender, e) =>
                {
                    TextBox textBox = comboBox.Template.FindName("PART_EditableTextBox", comboBox) as TextBox;

                    if (textBox != null)
                    {
                        textBox.SetValue(TextBox.MaxLengthProperty, args.NewValue);
                    }
                };
            }
        }
    }

F# 代码是这样的:

type myComboBoxProperties() =

    static let OnMaxLengthChanged  (myobj1 : DependencyObject, args : DependencyPropertyChangedEventArgs)  =

        let comboBox = myobj1 :?> ComboBox

        comboBox.Loaded.Subscribe (fun _ -> 
                                    let textBox : TextBox = comboBox.Template.FindName("PART_EditableTextBox", comboBox) :?> TextBox 
                                    match textBox with
                                    | null -> ()
                                    |_ -> textBox.SetValue(TextBox.MaxLengthProperty, args.NewValue))

    static let MaxLengthProperty = DependencyProperty.RegisterAttached("MaxLength", typeof<int>, typeof<myComboBoxProperties>, new UIPropertyMetadata(OnMaxLengthChanged))

    static member GetMaxLength (myobj : DependencyObject) = myobj.GetValue(MaxLengthProperty) :?> int

    static member SetMaxLength (myobj : DependencyObject, value : int) = myobj.SetValue(MaxLengthProperty, value)

我遇到的问题是我得到的 XAML 错误是:

默认值类型与属性类型MaxLength不匹配

我做错了什么?

【问题讨论】:

  • 你能提供一个堆栈跟踪吗?为了实验,您还可以尝试显式设置默认值。 new UIPropertyMetadata(0, OnMaxLengthChanged)); 例如。看起来错误发生在参数类型的checkautomatically generated 的类型时,框架默认值相等,这对我来说很奇怪。
  • 没有堆栈跟踪,我正在调试中尝试这个。我不能给出默认值,因为我不知道如何将 OnMaxLengthChanged 更改为 propertycallback。我是 F# 新手

标签: c# f# dependency-properties


【解决方案1】:

你可以试试这个

open System.Windows
open System.Windows.Controls

type MyComboBoxProperties() =

  static let OnMaxLengthChanged  (myobj1 : DependencyObject) (args : DependencyPropertyChangedEventArgs) =

    let comboBox = myobj1 :?> ComboBox

    comboBox.Loaded.Add (
      fun _ -> 
        let textBox : TextBox = comboBox.Template.FindName("PART_EditableTextBox", comboBox) :?> TextBox 
        match textBox with
        | null -> ()
        |_ -> textBox.SetValue(TextBox.MaxLengthProperty, args.NewValue)
      )

  static let MaxLengthProperty = 
    DependencyProperty.RegisterAttached(
      "MaxLength", 
      typeof<int>, 
      typeof<MyComboBoxProperties>, 
      UIPropertyMetadata(0, PropertyChangedCallback OnMaxLengthChanged)
      )

  static member GetMaxLength (myobj : DependencyObject) = myobj.GetValue(MaxLengthProperty) :?> int

  static member SetMaxLength (myobj : DependencyObject, value : int) = myobj.SetValue(MaxLengthProperty, value)

您的代码的主要区别在于 UIPropertyMetadata(0, PropertyChangedCallback OnMaxLengthChanged)OnMaxLengthChanged 转换为 PropertyChangedCallback

但是,即使每次更改最大值时,您订阅.Loaded 也让我感到奇怪。我怀疑你只喜欢第一次订阅?

【讨论】:

  • 我会试试这个!我只是想将 c# 项目转换为 f#。谢谢,我会让你知道它是如何工作的
  • 我认为您有两种方法可以解决...一种方法是提供您自己的ComboBoxTextBox 样式,该样式对附加的TemplateBinding 属性执行TemplateBinding。如果您想保持当前模式,一种方法是引入一个跟踪附加状态的属性。我可以证明这一点,但这是 IMO 的一个新问题。
猜你喜欢
  • 2011-08-19
  • 2011-12-01
  • 1970-01-01
  • 2019-07-26
  • 1970-01-01
  • 2018-06-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多