Состояние поведения элемента коллекции не отображается после изменения источника привязки списка - PullRequest
0 голосов
/ 01 сентября 2011

Я новичок в 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);
        }
    }

}

1 Ответ

1 голос
/ 01 сентября 2011

Когда вы только что добавили элементы, соответствующие контейнеры с их поведением еще не были созданы, и, следовательно, тип еще не связан, что делает уведомление бессмысленным.

Обычно вам не нужно поднимать уведомления снаружиустановщик свойства, поэтому я постараюсь избежать всего этого вручную.

Я не знаю, что делает ваше поведение, но если оно как-то влияет на тип, вы должны поместить эту логику уведомлений либо в установщик типаесли он есть или в OnAttached метод переопределения поведения bahaviour.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...