我有一个对象列表(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是非常其他的堆栈?
答案 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));
}