4

XamDataGrid最小限の手間でセルを再読み込みして再描画するようにviewmodelがビューに指示する方法が必要です。ソースを台無しにして、そのイベントを発生させることで持続不可能な回避策を実行したくありません(ソースが変更される可能性があります)。

理解しやすくするために、データに影響を与えず、グリッドでの表現方法(スケーリング、フォーマットなど)のみを保持する視覚的なキュー構成を保持するグローバル静的クラスがあります。視覚的なアクションはIValueConverter、フィールドにアタッチされた実装で発生します。これは問題なく機能します。キューが変更され、ビューモデルがそれにサブスクライブし、イベントが適切に発生したときに発生する静的イベントがあります。ここで、イベントハンドラーにグリッドを再描画させる必要があります。

助言がありますか?

編集:それが役立つ場合は、いくつかのコード:

コンバータ:

public class ScaleConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (targetType == typeof(double) || targetType == typeof(double?))
        {
            if (value == null && targetType == typeof(double?)) return null;  // short circuit for null->null, nothing to scale
            if (value is double) return (double)value / DisplayScale.Scale; // shortcut for direct scaling, no need to waste time on conversion
            try
            {
                return System.Convert.ToDouble(value) / DisplayScale.Scale; // for convertible values, eat conversion exception
            }
            catch (Exception) {};
            // if all esle fails return NaN
            return double.NaN; 
        }
        // fallthrough, return null, this should not happen, if it does it means converter is incomplete
        return null;
    }
 ...
}

DisplayScaleグローバル

public class DisplayScale: NotificationObject
{
    private static KeyValuePair<string, double> _ActiveScaling;
    private static readonly object _lockHandle = new object(); // note: should not contest, but just to be on the safe side
    public static event Action ScalingChanged;

    public static List<KeyValuePair<string, double>> ScaleList { get; private set; }

    static DisplayScale()
    {
        ScaleList = new List<KeyValuePair<string, double>>() 
        { 
            new KeyValuePair<string, double>("No scaling (1's)", 1d),
            new KeyValuePair<string, double>("Thousands (1,000's)", 1000d),
            new KeyValuePair<string, double>("Millions (1,000,000's)", 1000000d),
            new KeyValuePair<string, double>("Billions (1,000,000,000's)", 1000000000d)
         };
        ActiveScaling = ScaleList.First();  // OPTION: could be in per-user config
    }

    public static double Scale { get { return ActiveScaling.Value; } }
    public static KeyValuePair<string, double> ActiveScaling
    {
        get
        {
            lock (_lockHandle) return _ActiveScaling;
        }
        set
        {
            lock (_lockHandle)
            {
                _ActiveScaling = value;
                var eventCall = ScalingChanged;
                if (eventCall != null) eventCall();
            }
        }
    }
}

フィールドは次のように定義されます

// resource
<inf:ScaleConverter x:Key="ScaleConverter" />
// field
<igDP:Field Name="Deposit" Converter="{StaticResource ScaleConverter}">
4

2 に答える 2

4

コレクションビューがある場合は、単にRefresh()を呼び出します。

public class YourViewModel
{
  private ObservableCollection<YourDataClass> yourColl;

  public void YourViewModel()
  {
    yourColl = new ObservableCollection<YourDataClass>();
    YourCollectionView = CollectionViewSource.GetDefaultView(yourColl);
    DisplayScale.ScalingChanged += () => YourCollectionView.Refresh();
  }

  var ICollectionView yourCollView;
  public ICollectionView YourCollectionView
  {
    get { yourCollView; }
    set {
      yourCollView = value;
      RaisePropertyChanged("YourCollectionView");
    }
  }
}
于 2011-12-05T13:18:43.667 に答える
0

同じ問題が発生し、ViewModelにINotifyPropertyChangedを実装しても、グリッド行がObservableCollectionでバインドしているクラス(つまり、punker76の回答のYourDataClass)にINotifyPropertyChangedを実装していなかったことがわかりました。そのクラスに実装すると、すべてが期待どおりに更新され始めました。

「ソースをいじりたくない」とおっしゃっていたので、この解決策が受け入れられるかどうかはわかりませんが、この投稿を見つけた他の人にも共有したいと思いました。

于 2013-10-11T18:47:19.123 に答える