Observable Collection 不更新 UI
Observable Collection do not update the UI
我正在研究在可观察集合中添加和删除行的能力。
我有 UserControl 视图,ListView 绑定到 ObservableCollection。
我还删除了在 ViewModel 中运行的命令,但不更新 UI.
这是我在 ViewModel 上的代码,继承自 MvvmLight ViewModelBase class。
public class ProductInfoViewModel : ViewModelBase
{
#region Properties
private ObservableCollection<Product> _productList;
public ObservableCollection<Product> ProductList
{
get { return _productList; }
set
{
_productList = value;
RaisePropertyChanged("ProductList");
}
}
#endregion
#region Constructor
public ProductInfoViewModel()
{
ConnectWebService connect = new ConnectWebService();
string json = connect.getResponse(@"http://localhost:8082/products");
ProductList = JsonConvert.DeserializeObject<ObservableCollection<Product>>(json);
DeleteCommand = new RelayCommand<long>((id) => DeleteCommandHandler(id, ProductList));
}
#endregion
#region Commands
public ICommand DeleteCommand { get; private set; }
#endregion
#region CommandsHandlers
private void DeleteCommandHandler(long id, ObservableCollection<Product> productList)
{
try
{
productList.Remove(productList.Where(i => i.ProductId == id).First());
}
catch (Exception)
{
}
}
这是我在 XAML 中的代码:
<UserControl.DataContext>
<local:ProductInfoViewModel/>
</UserControl.DataContext>
<Grid>
<Grid Margin="0,50,0,100">
<ListView Margin="5" SelectionChanged="ListView_SelectionChanged" ItemsSource="{Binding ProductList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Foreground="Black" Background="White" BorderBrush="{x:Null}"
x:Name="ProductList">
<ListView.View>
<GridView>
<GridViewColumn Header="Kod" Width="50" DisplayMemberBinding="{Binding ProductCode}"/>
<GridViewColumn Header="Nazwa" Width="150" DisplayMemberBinding="{Binding ProductName}" />
<GridViewColumn Header="Typ" Width="150" DisplayMemberBinding="{Binding ProductType}" />
<GridViewColumn Header="Opis" Width="300" DisplayMemberBinding="{Binding ProductDescription}" />
<GridViewColumn Header="Dostępność" Width="150" DisplayMemberBinding="{Binding ProductAvability}" />
<GridViewColumn Width="80">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Content="Edytuj" Background="Transparent" BorderThickness="0" Foreground="Blue" Width="50" Margin="0" HorizontalAlignment="Center"
Click="Button_Click"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="80">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Content="Usuń" Background="Transparent" BorderThickness="0" Foreground="Blue" Width="50" Margin="0" HorizontalAlignment="Center"
Click="Delete_Click" Command="{Binding ProductInfoView.DeleteCommand, Mode=OneWay, Source={StaticResource Locator}}" CommandParameter="{Binding ProductId}"
/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
我的产品class实现了INotifyPropertyChanged接口,但我也用Fody
现在,只有当我将一个视图更改为另一个视图然后返回时,视图才会更新。
我不知道出了什么问题。
如有任何帮助,我将不胜感激!
当您从列表中删除项目时,您不会使用您的产品列表 setter,因此 RaisePropertyChanged
不会被调用。一个快速的解决方法是在删除项目后添加对 RaisePropertyChanged
的调用:
productList.Remove(productList.Where(i => i.ProductId == id).First());
RaisePropertyChanged("ProductList");
您正在将 Button
的 Command
属性 绑定到 Locator
资源返回的视图模型。您应该将它绑定到 ListView
绑定到的同一实例:
<DataTemplate>
<Button Content="Usuń" Background="Transparent" BorderThickness="0" Foreground="Blue" Width="50" Margin="0" HorizontalAlignment="Center"
Click="Delete_Click"
Command="{Binding DataContext.DeleteCommand, RelativeSource={RelativeSource AncestorType=ListView}}"
CommandParameter="{Binding ProductId}"/>
</DataTemplate>
我正在研究在可观察集合中添加和删除行的能力。 我有 UserControl 视图,ListView 绑定到 ObservableCollection。 我还删除了在 ViewModel 中运行的命令,但不更新 UI.
这是我在 ViewModel 上的代码,继承自 MvvmLight ViewModelBase class。
public class ProductInfoViewModel : ViewModelBase
{
#region Properties
private ObservableCollection<Product> _productList;
public ObservableCollection<Product> ProductList
{
get { return _productList; }
set
{
_productList = value;
RaisePropertyChanged("ProductList");
}
}
#endregion
#region Constructor
public ProductInfoViewModel()
{
ConnectWebService connect = new ConnectWebService();
string json = connect.getResponse(@"http://localhost:8082/products");
ProductList = JsonConvert.DeserializeObject<ObservableCollection<Product>>(json);
DeleteCommand = new RelayCommand<long>((id) => DeleteCommandHandler(id, ProductList));
}
#endregion
#region Commands
public ICommand DeleteCommand { get; private set; }
#endregion
#region CommandsHandlers
private void DeleteCommandHandler(long id, ObservableCollection<Product> productList)
{
try
{
productList.Remove(productList.Where(i => i.ProductId == id).First());
}
catch (Exception)
{
}
}
这是我在 XAML 中的代码:
<UserControl.DataContext>
<local:ProductInfoViewModel/>
</UserControl.DataContext>
<Grid>
<Grid Margin="0,50,0,100">
<ListView Margin="5" SelectionChanged="ListView_SelectionChanged" ItemsSource="{Binding ProductList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Foreground="Black" Background="White" BorderBrush="{x:Null}"
x:Name="ProductList">
<ListView.View>
<GridView>
<GridViewColumn Header="Kod" Width="50" DisplayMemberBinding="{Binding ProductCode}"/>
<GridViewColumn Header="Nazwa" Width="150" DisplayMemberBinding="{Binding ProductName}" />
<GridViewColumn Header="Typ" Width="150" DisplayMemberBinding="{Binding ProductType}" />
<GridViewColumn Header="Opis" Width="300" DisplayMemberBinding="{Binding ProductDescription}" />
<GridViewColumn Header="Dostępność" Width="150" DisplayMemberBinding="{Binding ProductAvability}" />
<GridViewColumn Width="80">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Content="Edytuj" Background="Transparent" BorderThickness="0" Foreground="Blue" Width="50" Margin="0" HorizontalAlignment="Center"
Click="Button_Click"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="80">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Content="Usuń" Background="Transparent" BorderThickness="0" Foreground="Blue" Width="50" Margin="0" HorizontalAlignment="Center"
Click="Delete_Click" Command="{Binding ProductInfoView.DeleteCommand, Mode=OneWay, Source={StaticResource Locator}}" CommandParameter="{Binding ProductId}"
/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
我的产品class实现了INotifyPropertyChanged接口,但我也用Fody
现在,只有当我将一个视图更改为另一个视图然后返回时,视图才会更新。 我不知道出了什么问题。 如有任何帮助,我将不胜感激!
当您从列表中删除项目时,您不会使用您的产品列表 setter,因此 RaisePropertyChanged
不会被调用。一个快速的解决方法是在删除项目后添加对 RaisePropertyChanged
的调用:
productList.Remove(productList.Where(i => i.ProductId == id).First());
RaisePropertyChanged("ProductList");
您正在将 Button
的 Command
属性 绑定到 Locator
资源返回的视图模型。您应该将它绑定到 ListView
绑定到的同一实例:
<DataTemplate>
<Button Content="Usuń" Background="Transparent" BorderThickness="0" Foreground="Blue" Width="50" Margin="0" HorizontalAlignment="Center"
Click="Delete_Click"
Command="{Binding DataContext.DeleteCommand, RelativeSource={RelativeSource AncestorType=ListView}}"
CommandParameter="{Binding ProductId}"/>
</DataTemplate>