Я новичок в WPF и недавно столкнулся с проблемой. Я получил ObservableCollection TankCars в моей ViewModel, которая является источником привязки для ListBox в представлении. ListBox имеет ItemTemplate, который определяет два поведения:
<i:Interaction.Behaviors>
<ei:DataStateBehavior x:Name="Type62DataStateBehavior" Binding="{Binding Type}" Value="62" TrueState="IsType62"/>
<ei:DataStateBehavior x:Name="Type66DataStateBehavior" Binding="{Binding Type}" Value="66" TrueState="IsType66"/>
</i:Interaction.Behaviors>
Когда я добавляю элементы в коллекцию, я вижу, что они появляются в списке. Но состояние не отображается, пока я не вызову TankCars [i] .RaisePropertyChanged ("Type")
Более того, когда мне нужно переключиться на другую коллекцию, я вызываю код:
TankCars = new ObservableCollection<TankCar> (GetTankCars());
RaisePropertyChanged("TankCars"); //to notify the ListBox
foreach (var car in TankCars) {car.RaisePropertyChanged("Type");} //make states change (not working)
и кажется, что после того, как я изменил привязку ItemSource посредством вызова события изменения свойства TankCars, состояния элементов не отображаются (TankCar PropertyChangedEvent в данный момент не привязан ни к чему). Если я помещаю кнопку в форму, которая запускает команду, которая вызывает car.RaisePropertyChanged ("Type") для элементов, она обновляет состояния элементов.
Таким образом, вопрос заключается в следующем: как сделать так, чтобы поведение элементов срабатывало после добавления новых элементов в коллекцию и после замены ее на другую? И почему состояния элементов не обновляются, когда я поднимаю PropertyChanged сразу после изменения источника элемента ListBox?
Обновление: решено с помощью приведенного ниже кода (также помог этот ответ ). И больше не нужно вручную поднимать PropertyChanged для коллекционных предметов, я счастлив :)
public class SmartDataStateBehavior : DataStateBehavior
{
protected override void OnAttached()
{
base.OnAttached();
if (AssociatedObject != null)
{
AssociatedObject.Loaded += AssociatedObjectLoaded;
}
}
protected override void OnDetaching()
{
base.OnDetaching();
if (AssociatedObject != null)
{
AssociatedObject.Loaded -= AssociatedObjectLoaded;
}
}
private void AssociatedObjectLoaded(object sender, RoutedEventArgs e)
{
if (Binding == null || Value == null) return;
if (Binding.ToString() == Value.ToString())
{
if (TrueState != null)
VisualStateManager.GoToElementState(AssociatedObject, TrueState, true);
}
else
{
if (FalseState != null)
VisualStateManager.GoToElementState(AssociatedObject, FalseState, true);
}
}
}