WPF - 刷新绑定到 ViewModel 的 ListView
WPF - Refresh ListView bound to ViewModel
我正在编写一个应用程序,遇到了一个显示来自视图模型的项目的 ListView 的问题;在所述视图模型“Selected”中有一个 属性,它只是一个布尔值,我将其绑定到 ListView 的“IsSelected”属性。
我有一个“清除选择”按钮,它会遍历 selected 的每个项目并将其设置为 false;这有效并且命令已更新并且按钮不再启用,因为 Selected == true
.
没有任何内容
图片中
项目已 selected;按钮可用。
“清除选择”按钮已按下
此时,我无法再单击控件 select 元素;我必须控制单击它以取消 select 它,这会使所有内容恢复为禁用状态并且没有 selected.
这是控件的 XAML - 不确定我做错了什么,但到目前为止我找不到答案。
<ListView ItemsSource="{Binding AssignableItems, UpdateSourceTrigger=PropertyChanged}" Grid.Row="2" SelectionMode="Extended">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem" BasedOn="{StaticResource lviStyleBase}">
<Setter Property="IsSelected" Value="{Binding Selected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Created" DisplayMemberBinding="{Binding ContactCreated}" Width="Auto" />
<GridViewColumn Header="Contact Name" DisplayMemberBinding="{Binding ContactName}" Width="Auto" />
<GridViewColumn Header="Company" DisplayMemberBinding="{Binding Company}" Width="Auto" />
</GridView>
</ListView.View>
</ListView>
这是视图模型:
namespace CSI.ViewModels
{
public class AssignViewModel
: ModelBase
{
#region Properties
private bool viewingFilters;
public bool Filtering
{
get { return viewingFilters; }
set { if ( SetValue(ref viewingFilters, value) ) Notify(); }
}
private bool assigning;
public bool Assigning
{
get { return assigning; }
set { if ( SetValue(ref assigning, value) ) Notify(); }
}
private string viewTitle = "Assign";
public string ViewTitle
{
get => $"{viewTitle}{(Filtered ? " (filtered)" : "")}";
}
private AssignFilterValuesModel filters;
public AssignFilterValuesModel Filters
{
get { return filters; }
set { SetValue(ref filters, value); }
}
public bool Filtered
{
get
{
if ( filters == null ) return false;
return assignables.Count() != AssignableItems.Count();
}
}
private bool loading;
public bool Loading
{
get { return loading; }
set { SetValue(ref loading, value); }
}
private ObservableCollection<AssignableWorkItemModel> assignables;
public ObservableCollection<AssignableWorkItemModel> AssignableItems
{
get
{
if ( assignables == null ) return null;
if ( Filters == null ) return assignables;
var retval = assignables.Where(x => 1 == 1);
if ( Filters.Dealers.Any(x => x.Selected) )
retval = retval.Where(x => filters.Dealers.Where(o => o.Selected).Select(o => o.Key).ToList().Contains(x.Dealer));
if ( Filters.VehicleModels.Any(x => x.Selected) )
retval = retval.Where(x => filters.VehicleModels.Where(o => o.Selected).Select(o => o.Key).ToList().Contains(x.VehicleModel));
return new ObservableCollection<AssignableWorkItemModel>(retval);
}
set => SetValue(ref assignables, value);
}
private ObservableCollection<AssignableWorkItemModel> selected;
public ObservableCollection<AssignableWorkItemModel> SelectedItems
{
get => selected;
set => SetValue(ref selected, value);
}
#endregion
#region Commands
private RelayCommand displayFilterScreen;
public void Execute_DisplayFilters(object _)
{
Filtering = true;
}
public bool CanExecute_DisplayFilters(object _) => !Filtering;
public RelayCommand DisplayFilters
{
get => displayFilterScreen ?? (displayFilterScreen = new RelayCommand(Execute_DisplayFilters, CanExecute_DisplayFilters));
}
private RelayCommand applyFilters;
public void Execute_ApplyFilters(object _)
{
Filtering = !Filtering;
Notify(nameof(AssignableItems));
Notify(nameof(Filtered));
Notify(nameof(ViewTitle));
}
public bool CanExecute_ApplyFilters(object _) => Filtering;
public RelayCommand ApplyFilters
{
get => applyFilters ?? (applyFilters = new RelayCommand(Execute_ApplyFilters, CanExecute_ApplyFilters));
}
private RelayCommand doAssign;
public void Execute_Assign(object _)
{
UserSelectWindow us = new UserSelectWindow();
us.Owner = Application.Current.MainWindow;
ViewModelServer.UserSelectVM.Prompt = "Select the user you wish to assign these items to";
}
public bool CanExecute_Assign(object _) => !Filtering && (bool)AssignableItems?.Any(x => x.Selected);
public RelayCommand Assign
{
get => doAssign ?? (doAssign = new RelayCommand(Execute_Assign, CanExecute_Assign));
}
private RelayCommand clrSelection;
public void Execute_ClearSelection(object _)
{
AssignableItems?.Where(x => x.Selected).ToList().ForEach(x => x.Selected = false);
}
public bool CanExecute_ClearSelection(object _) => (bool)AssignableItems?.Any(x => x.Selected);
public RelayCommand ClearSelection
{
get => clrSelection ?? (clrSelection = new RelayCommand(Execute_ClearSelection, CanExecute_ClearSelection));
}
#endregion
#region Constructors
#endregion
}
}
解决方法是为SelectedIndex添加绑定,调用ClearSelection时将其值设置为-1;来自 here
的小费
我正在编写一个应用程序,遇到了一个显示来自视图模型的项目的 ListView 的问题;在所述视图模型“Selected”中有一个 属性,它只是一个布尔值,我将其绑定到 ListView 的“IsSelected”属性。
我有一个“清除选择”按钮,它会遍历 selected 的每个项目并将其设置为 false;这有效并且命令已更新并且按钮不再启用,因为 Selected == true
.
图片中
项目已 selected;按钮可用。
“清除选择”按钮已按下
此时,我无法再单击控件 select 元素;我必须控制单击它以取消 select 它,这会使所有内容恢复为禁用状态并且没有 selected.
这是控件的 XAML - 不确定我做错了什么,但到目前为止我找不到答案。
<ListView ItemsSource="{Binding AssignableItems, UpdateSourceTrigger=PropertyChanged}" Grid.Row="2" SelectionMode="Extended">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem" BasedOn="{StaticResource lviStyleBase}">
<Setter Property="IsSelected" Value="{Binding Selected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Created" DisplayMemberBinding="{Binding ContactCreated}" Width="Auto" />
<GridViewColumn Header="Contact Name" DisplayMemberBinding="{Binding ContactName}" Width="Auto" />
<GridViewColumn Header="Company" DisplayMemberBinding="{Binding Company}" Width="Auto" />
</GridView>
</ListView.View>
</ListView>
这是视图模型:
namespace CSI.ViewModels
{
public class AssignViewModel
: ModelBase
{
#region Properties
private bool viewingFilters;
public bool Filtering
{
get { return viewingFilters; }
set { if ( SetValue(ref viewingFilters, value) ) Notify(); }
}
private bool assigning;
public bool Assigning
{
get { return assigning; }
set { if ( SetValue(ref assigning, value) ) Notify(); }
}
private string viewTitle = "Assign";
public string ViewTitle
{
get => $"{viewTitle}{(Filtered ? " (filtered)" : "")}";
}
private AssignFilterValuesModel filters;
public AssignFilterValuesModel Filters
{
get { return filters; }
set { SetValue(ref filters, value); }
}
public bool Filtered
{
get
{
if ( filters == null ) return false;
return assignables.Count() != AssignableItems.Count();
}
}
private bool loading;
public bool Loading
{
get { return loading; }
set { SetValue(ref loading, value); }
}
private ObservableCollection<AssignableWorkItemModel> assignables;
public ObservableCollection<AssignableWorkItemModel> AssignableItems
{
get
{
if ( assignables == null ) return null;
if ( Filters == null ) return assignables;
var retval = assignables.Where(x => 1 == 1);
if ( Filters.Dealers.Any(x => x.Selected) )
retval = retval.Where(x => filters.Dealers.Where(o => o.Selected).Select(o => o.Key).ToList().Contains(x.Dealer));
if ( Filters.VehicleModels.Any(x => x.Selected) )
retval = retval.Where(x => filters.VehicleModels.Where(o => o.Selected).Select(o => o.Key).ToList().Contains(x.VehicleModel));
return new ObservableCollection<AssignableWorkItemModel>(retval);
}
set => SetValue(ref assignables, value);
}
private ObservableCollection<AssignableWorkItemModel> selected;
public ObservableCollection<AssignableWorkItemModel> SelectedItems
{
get => selected;
set => SetValue(ref selected, value);
}
#endregion
#region Commands
private RelayCommand displayFilterScreen;
public void Execute_DisplayFilters(object _)
{
Filtering = true;
}
public bool CanExecute_DisplayFilters(object _) => !Filtering;
public RelayCommand DisplayFilters
{
get => displayFilterScreen ?? (displayFilterScreen = new RelayCommand(Execute_DisplayFilters, CanExecute_DisplayFilters));
}
private RelayCommand applyFilters;
public void Execute_ApplyFilters(object _)
{
Filtering = !Filtering;
Notify(nameof(AssignableItems));
Notify(nameof(Filtered));
Notify(nameof(ViewTitle));
}
public bool CanExecute_ApplyFilters(object _) => Filtering;
public RelayCommand ApplyFilters
{
get => applyFilters ?? (applyFilters = new RelayCommand(Execute_ApplyFilters, CanExecute_ApplyFilters));
}
private RelayCommand doAssign;
public void Execute_Assign(object _)
{
UserSelectWindow us = new UserSelectWindow();
us.Owner = Application.Current.MainWindow;
ViewModelServer.UserSelectVM.Prompt = "Select the user you wish to assign these items to";
}
public bool CanExecute_Assign(object _) => !Filtering && (bool)AssignableItems?.Any(x => x.Selected);
public RelayCommand Assign
{
get => doAssign ?? (doAssign = new RelayCommand(Execute_Assign, CanExecute_Assign));
}
private RelayCommand clrSelection;
public void Execute_ClearSelection(object _)
{
AssignableItems?.Where(x => x.Selected).ToList().ForEach(x => x.Selected = false);
}
public bool CanExecute_ClearSelection(object _) => (bool)AssignableItems?.Any(x => x.Selected);
public RelayCommand ClearSelection
{
get => clrSelection ?? (clrSelection = new RelayCommand(Execute_ClearSelection, CanExecute_ClearSelection));
}
#endregion
#region Constructors
#endregion
}
}
解决方法是为SelectedIndex添加绑定,调用ClearSelection时将其值设置为-1;来自 here
的小费