2011-12-04 34 views
4

我需要一種方式viewmodel指示XamDataGrid在視圖上重新讀取並重新繪製它的單元格很麻煩。我不希望混淆消息來源並通過提高其事件來做一些不可持續的解決方法(消息來源可能會改變)。原因xamDataGrid重繪

爲了使其更容易理解,我擁有一些視覺線索的配置不影響數據的一個全局靜態類,但只有他們自己的方式在網格(縮放,格式化等),其表示。視覺動作發生在附加到字段的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}"> 
+0

你能發表一些代碼嗎?你有cellvaluepresenter風格(s)? – punker76

+0

我可以發佈代碼,但它是無關緊要的,我只是希望網格做任何事情,當源引發ListChanged事件,而實際上不必訴諸提高ListChanged(因爲實際上它沒有改變,改變的是指令對於價值轉換器)。 – mmix

+0

您是否爲數據類實現了INotifyPropertyChanged接口? 「存款」屬性必須觸發PropertyChanged事件才能觸發您的ValueConverter。如果你有一個CollectionView而不是簡單的調用Refresh()。 – punker76

回答

4

如果你有一個蒐集ionview比調用簡單的刷新()。

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"); 
    } 
    } 
} 
+0

嗯,這可能實際上工作,只要Refresh()不會警告其他觀察者的數據源。我會嘗試一下。謝謝 – mmix

+0

它的工作原理,謝謝。 – mmix

0

我有the same issue,而且事實證明,即使我有我的ViewModel執行INotifyPropertyChanged,我是不是在類的網格行是在我的ObservableCollection(即YourDataClass在結合實施INotifyPropertyChanged的punker76的答案)。一旦我在該類上實現它,以及所有事情都開始按預期進行更新。

我知道你提到的「我不想與源混亂」,所以我不知道,如果這個解決方案是你可以接受的,但我想我會分享給其他人發現這個職位也是如此。