5

これは私の問題を説明するための基本的な例です。私が持っているとしましょう

ObservableCollection<int> Numbers {get; set;}

Numbers の合計を返す IValueConverter です。

通常、私が行うことは、IValueConverter を IMultiValueConverter に変更し、次のように Numbers.Count に 2 番目の値をバインドすることです

<MultiBinding Converter="{StaticResource SumTheIntegersConverter}">
    <Binding Path="Numbers"     />
    <Binding Path="Numbers.Count"   />
</MultiBinding>

ただし、この方法を使用して実際の問題を解決することはできません。私が考えていないコレクションが変更されたときにバインディングを更新するより良い方法があるはずです。項目が Numbers に追加および削除されたときに値コンバーターを実行するための最良の方法は何ですか?

4

4 に答える 4

2

これが実は意外と難しいのです。IValueConverter は更新されないため、期待どおりに動作しません。

コレクションアグリゲーターと呼ばれる Microsoft Expression Gallery にサンプルを書きました。これは、複雑な場合でも、集計を行う動作を介してこの作業を行うための有効なアプローチを示しています (あなたの場合はカウントですが、Sum、Average などもサポートしています)。あなた、コンバーターの代わりに。

于 2009-11-04T17:47:23.867 に答える
1

そして、私はコレクション(元のコンバーターと)を同期することになりました。たとえば、私の投稿の下部を見てください。

http://alexburtsev.wordpress.com/2011/03/05/mvvm-pattern-in-silverlight-and-wpf/

于 2011-03-06T06:10:59.413 に答える
1

私はうまくいくように見えるこのようなことをしてしまいました。それは最適な解決策とはほど遠いものであり、私はまだもっと良いものに興味がありますが、私の目的には合っているようです.

class CollectionChangedHandlingValueConverter : IValueConverter
{
    DependencyObject myTarget;
    DependencyProperty myTargetProperty;

    //If this ever needs to be called from XAML you can make it a MarkupExtension and use ProvideValue to set up the Target and TargetProperty
    public CollectionChangedHandlingValueConverter(DependencyObject target, DependencyProperty dp)
    {
        myTarget = target;
        myTargetProperty = dp;
    }

    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        INotifyCollectionChanged collection = value as INotifyCollectionChanged;
        if (collection != null)
        {
            //It notifies of collection changed, try again when it changes
            collection.CollectionChanged += DataCollectionChanged;
        }

        //Do whatever conversions here
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    #endregion

    void DataCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if ((myTarget != null) && (myTargetProperty != null))
        {
            BindingOperations.GetBindingExpressionBase(myTarget, myTargetProperty).UpdateTarget();
        }
    }
}
于 2009-11-06T16:24:40.530 に答える