5

以下のコードは私の現在の解決策です。

このコードが何をしているのかを理解するのに数分かかる場合は、ya と聞きます

これがあったとしても、これは醜い混乱です。私は別の方法を見つけるために殺します(しかし、それであなたが応答するのを思いとどまらせないでください... :-)。なんてこった、コンバーターのコードを削除して (実質的に) 省略したことさえありますが、このコードを見ると、まだ失読症のように感じます。

私が模倣しようとしているものの良い例は、FrameworkElement.ActualWidth プロパティです。Width プロパティが変更されるたびに、またはコントロールが再描画されるたびに、またはそれ以外のときに、ActualWidth プロパティがどのように計算され、再割り当てされるか知っていますか? ------

開発者の観点からは、データ バインディングが懸命に行われているように見えます。
ただし、ActualWidth は読み取り専用の依存関係プロパティです。マイクロソフトは、それを機能させるために、この巨大なコードのゴミ穴を通過する必要があるのでしょうか? それとも、データ バインディング システムの既存の機能を利用する簡単な方法はありますか?

public class foo : FrameworkElement
{
    [ValueConversion(typeof(string), typeof(int))]
    public class fooConverter : IValueConverter
    {   public object Convert(  object value, Type targetType,
                                object parameter, CultureInfo culture)
        { ... }
        public object ConvertBack(  object value, Type targetType,
                                    object parameter, CultureInfo culture)
        { ... }
    }

    private static readonly fooConverter fooConv = new fooConverter();



    private static readonly DependencyPropertyKey ReadOnlyIntPropertyKey =
        DependencyProperty.RegisterReadOnly( "ReadOnlyInt", typeof(int),
                                             typeof(foo), null);
    public int ReadOnlyInt
    {   get { return (int)GetValue(ReadOnlyIntPropertyKey.DependencyProperty); }
    }



    public static readonly DependencyProperty ReadWriteStrProperty =
        DependencyProperty.Register( "ReadWriteStr", typeof(string), typeof(foo),
                                     new PropertyMetadata(ReadWriteStr_Changed));
    public string ReadWriteStr
    {   get { return (string)GetValue(ReadWriteStrProperty); }
        set { SetValue(ReadWriteStrProperty, value); }
    }



    private static void ReadWriteStr_Changed(   DependencyObject d,
                                            DependencyPropertyChangedEventArgs e)
    {   try
        {   if (d is foo)
            {   foo f = d as foo;
                f.SetValue( ReadOnlyIntPropertyKey,
                            fooConv.Convert(f.ReadWriteStr, typeof(int), null,
                                            CultureInfo.CurrentCulture));
            }
        }
        catch { }
    }
}
4

3 に答える 3

4

残念ながら、あなたはあなたが持っているもののほとんどを必要とするでしょう。この場合、IValueConverterは必要ないため、次のように単純化できます。

public class foo : FrameworkElement
{
    private static readonly DependencyPropertyKey ReadOnlyIntPropertyKey =
        DependencyProperty.RegisterReadOnly( "ReadOnlyInt", typeof(int),
                                         typeof(foo), null);
    public int ReadOnlyInt
    {
       get { return (int)GetValue(ReadOnlyIntPropertyKey.DependencyProperty); }
    }

    public static readonly DependencyProperty ReadWriteStrProperty =
        DependencyProperty.Register( "ReadWriteStr", typeof(string), typeof(foo),
                                 new PropertyMetadata(ReadWriteStr_Changed));

    public string ReadWriteStr
    {
       get { return (string)GetValue(ReadWriteStrProperty); }
        set { SetValue(ReadWriteStrProperty, value); }
    }

    private static void ReadWriteStr_Changed(DependencyObject d,
                                        DependencyPropertyChangedEventArgs e)
    {
         foo f = d as foo;
         if (f != null)
         {
              int iVal;
              if (int.TryParse(f.ReadWriteStr, out iVal))
                  f.SetValue( ReadOnlyIntPropertyKey, iVal);
         }
    }
}
于 2009-08-19T18:01:00.450 に答える
1

あなたが示唆するほど悪くはありません、IMHO...

コンバーターを取り除くことができます:IValueConverterバインディング用です。コード ビハインドでの変換には必要ありません。それとは別に、どうすればもっと簡潔にできるかわかりません...

于 2009-08-19T17:55:27.747 に答える