Точного ответа нет, потому что ваша проблема должна быть прояснена лучше. В любом случае, событие PropertyChanged возникло просто для того, чтобы инициировать любое изменение подписчиков.
Вы не указываете, что это за элементы, как они размещены на панели и какой тип триггера они делают для запуска такого множества MeasureOverride. Вы можете выбрать другой подход: отсоединить все элементы, а затем связать их снова. Другое решение состоит в том, чтобы избежать любой привязки, которая может привести ко многим триггерам, и обновлять пользовательский интерфейс с помощью DispatcherTimer, вызывая InmvalidateVisual каждый тик.
Надеюсь, это поможет.
РЕДАКТИРОВАТЬ: я сделал трюк на ваших источниках. Я должен признать, что это то, что я никогда не использовал. Тем не менее, не стесняйтесь решать, использовать ли его.
1) поместите индикатор в MeasureOverride (избегайте точек останова):
protected override Size MeasureOverride(Size availableSize)
{
System.Console.WriteLine("measure-override");
return base.MeasureOverride(availableSize);
}
2) в классе MyViewModel добавьте это:
private bool _keepSync = true;
public bool KeepSync
{
get { return this._keepSync; }
set
{
if (this._keepSync != value)
{
this._keepSync = value;
this.Sync();
}
}
}
3) изменить набор MyProp (аналогично ширине):
set
{
if (value != prop)
{
this.prop = value;
if (this.KeepSync)
this.NotifyPropertyChanged("MyProp");
}
}
4) в классе Window1 добавьте следующее свойство DependencyProperty (полезно для демонстрации):
public static readonly DependencyProperty KeepSyncProperty = DependencyProperty.Register(
"KeepSync",
typeof(bool),
typeof(Window1),
new PropertyMetadata(
true,
(obj, args) =>
{
var ctl = (Window1)obj;
ctl.KeepSyncChanged(args);
}));
public bool KeepSync
{
get { return (bool)GetValue(KeepSyncProperty); }
set { SetValue(KeepSyncProperty, value); }
}
private void KeepSyncChanged(DependencyPropertyChangedEventArgs args)
{
foreach (var vm in this.ViewModelCollection)
vm.KeepSync = (bool)args.NewValue;
}
5) измените обработчик нажатия кнопки следующим образом:
private void Button_Click(object sender, RoutedEventArgs e)
{
for (var i = 0; i < ViewModelCollection.Count; i++)
{
ViewModelCollection[i].Width += 10;
ViewModelCollection[i].MyProp = string.Format("Item #{0}: {1}", i, ViewModelCollection[i].Width);
}
}
Что ж, если вы попытаетесь запустить приложение, при нажатии кнопки вы увидите несколько «переопределений мер», отображаемых в окне вывода Visual Studio. Это оригинальное поведение. (Обратите внимание также на флажок ckeckbox, помеченный как true, но НЕ снимайте его!)
Теперь закройте приложение и перезапустите. Теперь снимите флажок, затем нажмите кнопку. Вы заметите гораздо меньше вызовов «измерения с переопределением».
Надеюсь, это поможет.
Приветствия
РЕДАКТИРОВАТЬ 2: Черт! ... Я забыл кусок! ... Извините!
private void Sync()
{
if (this.KeepSync == false)
return;
this.NotifyPropertyChanged("MyProp");
this.NotifyPropertyChanged("Width");
}
Re-ура