admin管理员组文章数量:1357678
I have a very simple application, where I want populate the ListView
when the user presses a button. I am using CollectionViewSource
to update the ListView
when the button is pressed, but I cannot populate the ListView
items.
Here is the xaml
containing 2 buttons and a ListView
:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Margin="20" Grid.Row="0" Orientation="Horizontal">
<Button Command="{Binding GetAllDoorItemsCommand}">Get All Door Items</Button>
<Button Margin="20,0,0,0">Modiy Door Open Close</Button>
</StackPanel>
<ListView Grid.Row="1" Margin="0,20,0,0" x:Name="lstViewLockItems" ItemsSource="{Binding DoorCollection}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Height="80" Width="80">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="pack://application:,,,/Images/door.jpg"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding Open}" Value="True">
<Setter Property="Source" Value="pack://application:,,,/Images/dooropen.jpg"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
In the code behind, I am setting the DataContext
as follows:
public class MainWindowViewModel {
private ICollectionView _doorView;
public ICollectionView DoorCollection {
get {
return _doorView;
}
set {
_doorView = value;
}
}
public ICommand GetAllDoorItemsCommand {
get;
set;
}
public MainWindowViewModel() {
GetAllDoorItemsCommand = new RelayCommand < object > (GetAllItems);
}
private void GetAllItems(object obj) {
var Items = new List < Door > ();
Items.Add(new Door() {
Name = "Front", Open = true
});
Items.Add(new Door() {
Name = "Back", Open = false
});
DoorCollection = CollectionViewSource.GetDefaultView(Items);
DoorCollection.Refresh();
}
}
public class Door: INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
private string _name;
public string Name {
get => _name;
set {
_name = value;
OnPropertyChanged("Name");
}
}
private bool _open;
public bool Open {
get => _open;
set {
_open = value;
OnPropertyChanged("Open");
}
}
protected virtual void OnPropertyChanged(string propertyName) {
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
I would appreciate any help.
I have a very simple application, where I want populate the ListView
when the user presses a button. I am using CollectionViewSource
to update the ListView
when the button is pressed, but I cannot populate the ListView
items.
Here is the xaml
containing 2 buttons and a ListView
:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Margin="20" Grid.Row="0" Orientation="Horizontal">
<Button Command="{Binding GetAllDoorItemsCommand}">Get All Door Items</Button>
<Button Margin="20,0,0,0">Modiy Door Open Close</Button>
</StackPanel>
<ListView Grid.Row="1" Margin="0,20,0,0" x:Name="lstViewLockItems" ItemsSource="{Binding DoorCollection}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Height="80" Width="80">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="pack://application:,,,/Images/door.jpg"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding Open}" Value="True">
<Setter Property="Source" Value="pack://application:,,,/Images/dooropen.jpg"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
In the code behind, I am setting the DataContext
as follows:
public class MainWindowViewModel {
private ICollectionView _doorView;
public ICollectionView DoorCollection {
get {
return _doorView;
}
set {
_doorView = value;
}
}
public ICommand GetAllDoorItemsCommand {
get;
set;
}
public MainWindowViewModel() {
GetAllDoorItemsCommand = new RelayCommand < object > (GetAllItems);
}
private void GetAllItems(object obj) {
var Items = new List < Door > ();
Items.Add(new Door() {
Name = "Front", Open = true
});
Items.Add(new Door() {
Name = "Back", Open = false
});
DoorCollection = CollectionViewSource.GetDefaultView(Items);
DoorCollection.Refresh();
}
}
public class Door: INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
private string _name;
public string Name {
get => _name;
set {
_name = value;
OnPropertyChanged("Name");
}
}
private bool _open;
public bool Open {
get => _open;
set {
_open = value;
OnPropertyChanged("Open");
}
}
protected virtual void OnPropertyChanged(string propertyName) {
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
I would appreciate any help.
Share Improve this question edited Apr 1 at 11:54 AztecCodes 5966 gold badges16 silver badges30 bronze badges asked Mar 28 at 18:32 nikhilnikhil 1,7603 gold badges26 silver badges64 bronze badges 3 |1 Answer
Reset to default 1According to the documentation (emphasis mine):
You can think of a collection view as a layer on top of a binding source collection that allows you to navigate and display the collection based on sort, filter, and group queries, all without having to manipulate the underlying source collection itself. If the source collection implements the INotifyCollectionChanged interface, the changes that raise the CollectionChanged event are propagated to the views.
So, the underlying collection is responsible for notifying about changes, and List
does not do that. A good choice would be ObservableCollection
. Here is a simplified implementation using your code:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
GetAllDoorItemsCommand = new RelayCommand<object>(GetAllItems);
DoorCollection = CollectionViewSource.GetDefaultView(_doorView);
}
private readonly ObservableCollection<Door> _doorView = new();
public ICollectionView DoorCollection { get; }
public ICommand GetAllDoorItemsCommand { get; }
private void GetAllItems(object obj)
{
_doorView.Clear();
_doorView.Add(new Door { Name = "Front", Open = true });
_doorView.Add(new Door { Name = "Back", Open = false });
DoorCollection.Refresh();
}
}
本文标签: cWPF CollectionViewSource not updating UIStack Overflow
版权声明:本文标题:c# - WPF CollectionViewSource not updating UI - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744018697a2576812.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
DoorCollection
property is implemented. You are assigning a new value to it(CollectionViewSource.GetDefaultView(Items))
, but your UI isn't being notified that the DoorCollection property has changed. This is because you're not raising thePropertyChanged
event when settingDoorCollection
. – AztecCodes Commented Mar 28 at 19:01