将堆栈(可以切换)绑定到ListBox

时间:2018-05-26 17:56:20

标签: c# wpf data-binding

我有一个对象列表(Man),每个对象都包含Stack个状态。 我有一个调试窗口,显示Man选定的 ListBox堆栈。 我有一个TabControl,用于选择要调试的人。

为了能够选择正确的绑定,我创建了一个属性,该属性返回StateStack所选索引处的人的TabControl

public object StateStack => Men[DebugIndex].States;

DebugIndex绑定到TabControl的{​​{1}}属性。为了让SelectedIndex更新DebugIndex来展示,我使用了StateStack

OnPropertyChanged

问题是,当public int DebugIndex { get => _debugIndex; set { _debugIndex = value; OnPropertyChanged(nameof(StateStack)); } } TabControl发生变化时,SelectedIndex奇怪地混乱了!事情是,它只在视图中混乱,而不是在数据中。

我认为这是因为我改变了Binding的引用它是另一个堆栈,但我不知道如何解决这个问题......

顺便说一句,它在我添加所有Man对象并在开始时初始化它们的StateStack时起作用。但是一旦我稍后添加一个Man(并初始化它的StateStack),例如当我点击一个Button时,它就不再起作用了......

Stack

我的观看代码:

public sealed partial class MainWindow : INotifyPropertyChanged {

    private int _debugIndex;

    public ObservableCollection<Man> Men { get; } = new ObservableCollection<Man>();

    public MainWindow() {
        Men.Add(new Man {Index = 0, States = new StateStack()});

        InitializeComponent();

        Men[0].States.Push(new State {Name = "Falling1"});
        Men[0].States.Push(new State {Name = "Walking1"});

        //this is simplified code. I push states here because in my program it's done during runtime (not during initialization)
    }

    public object StateStack => Men[DebugIndex].States;

    public int DebugIndex {
        get => _debugIndex;
        set {
            _debugIndex = value;
            OnPropertyChanged(nameof(StateStack));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged([CallerMemberName] string propertyName = null) {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e) {
        Men.Add(new Man {Index = 1, States = new StateStack()});

        Men[1].States.Push(new State {Name = "Falling2"});
        Men[1].States.Push(new State {Name = "Walking2"});
        Men[1].States.Push(new State {Name = "Running2"});
    }
}

public class Man {
    public int Index { get; set; }
    public StateStack States { get; set; }
}

public class State {
    public string Name { private get; set; }

    public override string ToString() {
        return Name;
    }
}

public sealed class StateStack : Stack<State>, INotifyCollectionChanged {

    public new void Push(State item) {
        base.Push(item);

        OnCollectionChanged(
            new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, Count - 1));
    }

    public event NotifyCollectionChangedEventHandler CollectionChanged;

    private void OnCollectionChanged(NotifyCollectionChangedEventArgs e) {
        CollectionChanged?.Invoke(this, e);
    }
}

我可以对绑定说什么,当DebugIndex被更改时,StateStack是非常其他的堆栈

1 个答案:

答案 0 :(得分:1)

我已经模拟了您的方案,并且观察到Push方法存在问题,NotifyCollectionChangedEventArgs项目的更改方式是如何传播到源代码的。当前代码通知项目从结束索引更改(但对于堆栈,项目在顶部添加))。如果将通知开始索引更新为0 NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, 0),则绑定源将在视图中以适当的顺序显示该项。你可以阅读NotifyCollectionChangedEventArgs here

public new void Push(State item) {
    base.Push(item);

    OnCollectionChanged(
        new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, 0));
}