尽管有数据绑定,我的列表框在删除或添加项目时不会更新
My ListBox doesn't update when deleting or adding items, despite data binding
我的所有数据绑定在整个应用程序中都有效。我已经尝试了数据绑定 ItemsSource 的所有模式。列表在开始时加载,但当我使用我制作的上下文菜单时不会更新。我已经用 WriteLine
进行了测试,以确保其他一切正常,确实如此。
XAML
<ListBox Grid.Row="1" SelectionMode="Single" BorderThickness="0"
SelectionChanged="ListBox_SelectionChanged"
SelectedIndex="{Binding Path=Data.SelectedFeedIndex, Mode=TwoWay}"
SelectedItem="{Binding Path=Data.SelectedFeed, Mode=TwoWay}"
ItemsSource="{Binding Path=Data.Feeds}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding Path=Title}" MouseDown="TextBlock_MouseDown" />
<TextBox Text="{Binding Path=Title}"
Visibility="Collapsed" KeyDown="TextBox_KeyDown" Padding="1" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ContextMenu>
<ContextMenu>
<MenuItem Header="New" Command="{Binding Path=Data.NewFeed}" />
<MenuItem Header="Delete" Command="{Binding Path=Data.DeleteFeed}" />
</ContextMenu>
</ListBox.ContextMenu>
<ListBox.InputBindings>
<KeyBinding Key="Delete" Command="{Binding Path=Data.DeleteFeed}" />
</ListBox.InputBindings>
</ListBox>
属性
private List<Feed> _Feeds = new List<Feed>();
public List<Feed> Feeds
{
get
{
return _Feeds;
}
set
{
_Feeds = value;
onPropertyChanged("Feeds");
}
}
命令
public ICommand DeleteFeed
{
get
{
return new RelayCommand(ExecuteDeleteFeed, CanDeleteFeed);
}
}
public void ExecuteDeleteFeed(object parameter)
{
Feeds.RemoveAt(SelectedFeedIndex);
SelectedFeedIndex = nextIndex;
onPropertyChanged("Feeds");
}
public bool CanDeleteFeed(object parameter)
{
return Feeds.Count > 1;
}
我通过与上面的 ListBox 绑定来接收索引:
private int _SelectedFeedIndex;
public int SelectedFeedIndex
{
get
{
return _SelectedFeedIndex;
}
set
{
_SelectedFeedIndex = value;
onPropertyChanged("SelectedFeedIndex");
}
}
编辑
我尝试更改为 ObservableCollection
,但出现以下错误。
System.Windows.Data Error: 40 : BindingExpression path error: 'Feeds' property not found on 'object' ''Library' (HashCode=60811181)'. BindingExpression:Path=Data.Feeds; DataItem='MainViewModel' (HashCode=34760343); target element is 'ListBox' (Name=''); target property is 'ItemsSource' (type 'IEnumerable')
System.Windows.Data Error: 40 : BindingExpression path error: 'Feeds' property not found on 'object' ''Library' (HashCode=60811181)'. BindingExpression:Path=Data.Feeds; DataItem='MainViewModel' (HashCode=34760343); target element is 'ComboBox' (Name=''); target property is 'ItemsSource' (type 'IEnumerable')
新的属性
ObservableCollection<Feed> Feeds = new ObservableCollection<Feed>();
哦,好的。我把它变成了属性。现在可以了。非常感谢。我认为如果您不对所有属性手动使用 INotifyProperty,则只需要 ObservableCollection。现在说得通了。
您需要将 List 更改为 ObservableCollection,因为 List class 不会生成事件来通知其内容已更改。结果,ListBox 将显示 List 的初始内容,但之后永远不会更新。 ObservableCollection 确实会生成更改事件并将执行您需要的操作。
我的所有数据绑定在整个应用程序中都有效。我已经尝试了数据绑定 ItemsSource 的所有模式。列表在开始时加载,但当我使用我制作的上下文菜单时不会更新。我已经用 WriteLine
进行了测试,以确保其他一切正常,确实如此。
XAML
<ListBox Grid.Row="1" SelectionMode="Single" BorderThickness="0"
SelectionChanged="ListBox_SelectionChanged"
SelectedIndex="{Binding Path=Data.SelectedFeedIndex, Mode=TwoWay}"
SelectedItem="{Binding Path=Data.SelectedFeed, Mode=TwoWay}"
ItemsSource="{Binding Path=Data.Feeds}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding Path=Title}" MouseDown="TextBlock_MouseDown" />
<TextBox Text="{Binding Path=Title}"
Visibility="Collapsed" KeyDown="TextBox_KeyDown" Padding="1" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ContextMenu>
<ContextMenu>
<MenuItem Header="New" Command="{Binding Path=Data.NewFeed}" />
<MenuItem Header="Delete" Command="{Binding Path=Data.DeleteFeed}" />
</ContextMenu>
</ListBox.ContextMenu>
<ListBox.InputBindings>
<KeyBinding Key="Delete" Command="{Binding Path=Data.DeleteFeed}" />
</ListBox.InputBindings>
</ListBox>
属性
private List<Feed> _Feeds = new List<Feed>();
public List<Feed> Feeds
{
get
{
return _Feeds;
}
set
{
_Feeds = value;
onPropertyChanged("Feeds");
}
}
命令
public ICommand DeleteFeed
{
get
{
return new RelayCommand(ExecuteDeleteFeed, CanDeleteFeed);
}
}
public void ExecuteDeleteFeed(object parameter)
{
Feeds.RemoveAt(SelectedFeedIndex);
SelectedFeedIndex = nextIndex;
onPropertyChanged("Feeds");
}
public bool CanDeleteFeed(object parameter)
{
return Feeds.Count > 1;
}
我通过与上面的 ListBox 绑定来接收索引:
private int _SelectedFeedIndex;
public int SelectedFeedIndex
{
get
{
return _SelectedFeedIndex;
}
set
{
_SelectedFeedIndex = value;
onPropertyChanged("SelectedFeedIndex");
}
}
编辑
我尝试更改为 ObservableCollection
,但出现以下错误。
System.Windows.Data Error: 40 : BindingExpression path error: 'Feeds' property not found on 'object' ''Library' (HashCode=60811181)'. BindingExpression:Path=Data.Feeds; DataItem='MainViewModel' (HashCode=34760343); target element is 'ListBox' (Name=''); target property is 'ItemsSource' (type 'IEnumerable')
System.Windows.Data Error: 40 : BindingExpression path error: 'Feeds' property not found on 'object' ''Library' (HashCode=60811181)'. BindingExpression:Path=Data.Feeds; DataItem='MainViewModel' (HashCode=34760343); target element is 'ComboBox' (Name=''); target property is 'ItemsSource' (type 'IEnumerable')
新的属性
ObservableCollection<Feed> Feeds = new ObservableCollection<Feed>();
哦,好的。我把它变成了属性。现在可以了。非常感谢。我认为如果您不对所有属性手动使用 INotifyProperty,则只需要 ObservableCollection。现在说得通了。
您需要将 List 更改为 ObservableCollection,因为 List class 不会生成事件来通知其内容已更改。结果,ListBox 将显示 List 的初始内容,但之后永远不会更新。 ObservableCollection 确实会生成更改事件并将执行您需要的操作。