目前,我正在开发一个简单的任务管理器应用程序来锻炼我的 Windows 10 开发技能,使用通用 Windows 应用程序 (UWP) 模板和 MVVM 设计模式。
在我的 ViewModel(实现 INotifyPropertyChanged
)中,我有一个 ObservableCollection<BasicTask>
这是数据绑定(bind)到 ListView
在 XAML 中,其中 BasicTask
是我开发的一个简单类。
我的命令在 ViewModel 中实例化为属性,并数据绑定(bind)到(在本例中为)AppBarButton
的“命令”属性。用户界面元素。该命令的作用是调用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();
}
DeleteTask()
ViewModel 中的方法影响 ObservableCollection<BasicTask>
,正如我之前所说,数据绑定(bind)到 ListView
因此(据我所知)应该立即将更改推送到 ListView
. 而这正是它不做的 :(
我可以确认命令正确调用了 ViewModel 中的方法,因为我替换了 DeleteTask()
的主体使用 await new MessageDialog("").ShowAsync();
的方法,这奏效了。
我已经在许多项目中尝试过此方法,但到目前为止都没有成功。一个明显的解决方案是 here ,但是,Visual Studio 通知 CommandManager 类不存在:/
更新
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
绑定(bind)到 Items
所选属性 TaskList
在任务列表中 ObservableCollection
, 这是第二个 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 XAML
class 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,我在这个 case 中使用了 Jerry Nixon - MSFT 提供的解决方案
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上查看我的可行样本
关于c# - ICommand 不将更改推送到 Windows UWP 中的 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33029841/