对于以下问题,我需要您的建议:
假设您有一个 MyView 类型 (UserControl),它定义了一个路由事件 IsSelectedChanged。每次更改 myView.IsSelected 属性值时都会引发它。
此外,您有一个 MyContainer (Canvas),其中包含非常(非常!)大量 MyView 类型的子项。MyContainer 已路由事件 MyViewsSelectionChanged,每当 MyViewsSelection 发生更改时都会引发该事件。MyViewsSelection 是一组 MyView 对象,其 IsSelected 属性设置为true。MyContainer 将为每个孩子处理 MyView.IsSelectedChanged 并将其 MyViewSelection 状态提供给 MyContainerParent(面板)
MyContainerParent 将处理 myContainer.MyViewsSelectionChanged 事件
我担心的问题是,我的应用程序对于大量 MyView 对象的选择会表现不佳,从而导致某种“野火”事件。
任何防止该问题的建议,将不胜感激!
谢谢
一些代码:
BatchView.IsSelectedChanged (MyView):
public static readonly RoutedEvent IsSelectedChangedEvent = EventManager.RegisterRoutedEvent(
"IsSelectedChanged",
RoutingStrategy.Direct,
typeof(RoutedEventHandler),
typeof(BatchView)
);
/// <summary>
/// Occurs when IsSelected property value is changed.
/// </summary>
public event RoutedEventHandler IsSelectedChanged {
add { AddHandler(IsSelectedChangedEvent, value); }
remove { RemoveHandler(IsSelectedChangedEvent, value); }
}
void RaiseIsSelectionChangedEvent() {
RoutedEventArgs e = new RoutedEventArgs(IsSelectedChangedEvent, this.BatchViewModel);
RaiseEvent(e);
Logger.Debug("IsSelectionChanged: {0}; IsSelected = {1}", this.BatchViewModel.Description, this.IsSelected);
}
public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.RegisterAttached(
"IsSelected",
typeof(bool),
typeof(BatchView),
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(delegate(DependencyObject sender, DependencyPropertyChangedEventArgs args) {
BatchView view = sender as BatchView;
bool isSelected = Convert.ToBoolean(args.NewValue);
if ( view != null ) {
view._border.BorderBrush = isSelected ? Brushes.Magenta : Brushes.Black;
view.IsPrimarySelected = view.IsFocused && isSelected;
}
})));
/// <summary>
/// Get/set whether this batch view is selected
/// </summary>
public bool IsSelected {
get { return (bool)GetValue(IsSelectedProperty); }
set {
if ( IsSelected != value ) {
SetValue(IsSelectedProperty, value);
RaiseIsSelectionChangedEvent();
}
}
}
甘特视图(MyContainer):
static GanttView() {
EventManager.RegisterClassHandler(typeof(BatchView), BatchView.IsSelectedChangedEvent, new RoutedEventHandler(delegate(object sender, RoutedEventArgs args) {
var batchView = sender as BatchView;
var ganttView = batchView.FindVisualParent<GanttView>();
if ( ganttView != null ) {
ganttView.RaiseBatchViewsSelectionChangedEvent();
}
args.Handled = true;
}));
}
public static readonly RoutedEvent BatchViewsSelectionChangedEvent = EventManager.RegisterRoutedEvent(
"BatchViewsSelectionChanged",
RoutingStrategy.Direct,
typeof(RoutedEventHandler),
typeof(GanttView)
);
public event RoutedEventHandler BatchViewsSelectionChanged {
add { AddHandler(BatchViewsSelectionChangedEvent, value); }
remove { RemoveHandler(BatchViewsSelectionChangedEvent, value); }
}
void RaiseBatchViewsSelectionChangedEvent() {
RoutedEventArgs e = new RoutedEventArgs(BatchViewsSelectionChangedEvent, this);
RaiseEvent(e);
Logger.Debug("BatchViewsSelectionChanged: {0};", this.SelectedBatchViews.Count());
}
调度器视图(MyContainerParent):
static SchedulerView() {
EventManager.RegisterClassHandler(typeof(GanttView), GanttView.BatchViewsSelectionChangedEvent, new RoutedEventHandler(delegate(object sender, RoutedEventArgs args) {
var schedulerView = ((GanttView)sender).FindVisualParent<SchedulerView>();
if ( schedulerView != null ) {
if ( schedulerView.BatchesSelectionChanged != null ) {
BatchesSelectionChangedEventArgs e = new BatchesSelectionChangedEventArgs();
e.SelectedBatchesCount = schedulerView.GanttView.SelectedBatchViews.Count();
e.TotalBatchesDuration = schedulerView.GanttView.SelectedBatchViews.Sum<BatchView>(bv => bv.BatchViewModel.Model.Duration);
e.TotalBatchesQuantity = schedulerView.GanttView.SelectedBatchViews.Sum<BatchView>(bv => bv.BatchViewModel.Model.Quantity);
schedulerView.BatchesSelectionChanged(schedulerView, e);
}
}
}));
}