2015-05-16 16 views
7

Sto tentando di convertire una proprietà di dipendenza C# che limita la lunghezza massima del testo immesso in un controllo ComboBox a F #. Il programma è un programma MVVM che utilizza F # per il modello e viewmodel e C# per la vista. il codice di lavoro C# è questo:Proprietà di dipendenza in F # Il valore predefinito non corrisponde a

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

Il codice F # è questo:

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) 

Il problema che sto avendo è che l'errore XAML che ottengo è:

tipo di valore predefinito non corrisponde al tipo di immobile MaxLength

Cosa sto facendo wro ng?

+1

È possibile fornire una traccia stack? Puoi anche provare a impostare un valore predefinito esplicitamente a scopo di sperimentazione. 'new UIPropertyMetadata (0, OnMaxLengthChanged));' ad esempio. Sembra che si verifichi un errore al momento di [check] (http://referencesource.microsoft.com/#WindowsBase/Base/System/Windows/DependencyProperty.cs.4aed0e0929184ad0) di parameterType e tipo di [generato automaticamente] (http://referencesource.microsoft.com/#WindowsBase/Base/System/Windows/DependencyProperty.cs,c2c01ce10ae3e445,references) per valore di default del framework uguaglianza, che per me è difficile. –

+0

non c'è traccia di stack, sto provando questo in debug. Non posso dare un valore predefinito perché non so come modificare OnMaxLengthChanged in una proprietà callback. Sono nuovo di F # –

risposta

4

Si potrebbe provare questo

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) 

La differenza chiave per il codice è questo UIPropertyMetadata(0, PropertyChangedCallback OnMaxLengthChanged) che converte in un OnMaxLengthChangedPropertyChangedCallback.

Ma mi sembra strano che tu abbia sottoscritto lo .Loaded anche ogni volta che cambia il valore massimo. Sospetto che ti piaccia iscriversi solo la prima volta?

+0

lo proverò! Stavo solo cercando di convertire un progetto C# in f #. grazie ti farò sapere come funziona –

+0

Penso che tu abbia due modi per andare ... un modo è quello di fornire il proprio stile 'ComboBoxTextBox' che fa un' TemplateBinding' alla proprietà 'MaxLength' allegata. Se ti piace mantenere il tuo attuale schema, un approccio è quello di introdurre una proprietà che tenga traccia dello stato aggiuntivo. Posso dimostrarlo, ma è una nuova domanda IMO. – FuleSnabel