目前,我正在开发一个简单的任务管理器应用程序,以使用通用Windows应用程序(UWP)模板和MVVM设计模式来运用我的Windows 10开发技能.
在我的ViewModel(实现INotifyPropertyChanged)中,我有一个ObservableCollection< BasicTask>它是数据绑定到XAML中的ListView,其中BasicTask是我开发的一个简单类.
我的命令在ViewModel中作为属性进行实例化,并且数据绑定到(在这种情况下)AppBarButton UI元素的“Command”属性.该命令的功能是调用ViewModel中的一个方法,该方法在命令的构造函数中定义,如此;
class DeleteTaskCommand : ICommand
{
public DeleteTaskCommand(MainViewModel viewModel)
{
ViewModel = viewModel;
}
public MainViewModel ViewModel { get; private set; }
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter) => (ViewModel.SelectedTask != BasicTask.Default) ? true : false;
public void Execute(object parameter) => ViewModel.DeleteTask();
}
ViewModel中的DeleteTask()方法会影响ObservableCollection< BasicTask>,正如我之前所说,它是数据绑定到ListView,因此(据我所知)应该立即将更改推送到ListView.而这正是不做的事:(
我可以确认该命令正确地调用了ViewModel中的方法,因为我用等待新的MessageDialog(“”)替换了DeleteTask()方法的主体.显示了ShowAsync();.
到目前为止,我已经尝试过许多项目并没有成功.一个明显的解决方案是here,但Visual Studio通知CommandManager类不存在:/
UPDATE
上面提到的ListView的XAML如下:
<ListView ItemsSource="{Binding TaskLists}"
SelectedIndex="{Binding SelectedTaskListIndex, Mode=TwoWay}"
SelectionMode="Single">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Grid>[...]</Grid>
<TextBlock Text="{Binding Title}"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
TaskLists是一个ObservableCollection< TaskList> TaskLists和TaskList类如下;
class TaskList
{
public string Title { get; set; }
public string Description { get; set; }
public List<BasicTask> Items { get; set; }
public static TaskList Generate(string title, string description, List<BasicTask> items)
=> new TaskList() { Title = title, Description = description, Items = items };
}
第二个ListView绑定到TaskLists ObservableCollection中所选TaskList的Items属性,它是第二个未更新的ListView.
public int SelectedTaskListIndex
{
get { return selectedTaskListIndex; }
set
{
selectedTaskListIndex = value;
SelectedTaskList = (value != -1) ? TaskLists[value] : TaskList.Default;
RaisePropertyChanged(nameof(SelectedTaskListIndex));
}
}
public TaskList SelectedTaskList
{
get { return selectedTaskList; }
set
{
selectedTaskList = value;
RaisePropertyChanged(nameof(SelectedTaskList));
}
}
<ListView ItemsSource="{Binding SelectedTaskList.Items}"
任何和所有这个问题的帮助将不胜感激:)
解决方法:
In my ViewModel (which implements INotifyPropertyChanged), I’ve got an
ObservableCollection which is databound to a ListView in
XAMLclass TaskList {
public string Title { get; set; }
public string Description { get; set; }
public List Items { get; set; } … }
实际上,我注意到你在TaskList中创建了一个List属性,如果用ObservableCollection替换它并以正确的方式通知UI,UI更新应该有效,这是我的DeleteTask()方法:
private void DeleteTask()
{
SelectedTaskList.Items.Remove(SelectedTask);
}
SelectedTaskList和SelectedTask都已及时通知UI.
顺便说一下,为了更新/提升CanExecuteChanged,我使用了Jerry Nixon提供的这个解决方案 – MSFT在这个case
public TaskList SelectedTaskList
{
get { return selectedTaskList; }
set
{
selectedTaskList = value;
RaisePropertyChanged(nameof(SelectedTaskList));
DeleteTaskCommand.RaiseCanExecuteChanged();
}
}
public BasicTask SelectedTask
{
get { return selectedTask; }
set
{
selectedTask = value;
RaisePropertyChanged(nameof(SelectedTask));
DeleteTaskCommand.RaiseCanExecuteChanged();
}
}
请在Github检查我的可行样本