我需要一种方法让viewmodel指示视图上的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 global
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 :(得分: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");
}
}
}
答案 1 :(得分:0)
我有the same issue,事实证明,即使我的ViewModel实现了INotifyPropertyChanged,我也没有在我的ObservableCollection中绑定网格行的类上实现INotifyPropertyChanged(即 YourDataClass 在punker76的回答中)。一旦我在该类上实现了它,一切都按预期开始更新。
我知道你提到“我不想弄乱这个来源”所以我不确定这个解决方案是否适合你,但我想我会分享给其他人发现这篇文章。