【问题标题】:ICommand not pushing changes to the UI in Windows UWPICommand 未将更改推送到 Windows UWP 中的 UI
【发布时间】:2015-10-09 04:18:23
【问题描述】:

目前,我正在使用通用 Windows 应用程序 (UWP) 模板和 MVVM 设计模式开发一个简单的任务管理器应用程序来锻炼我的 Windows 10 开发技能。

在我的 ViewModel(实现 INotifyPropertyChanged)中,我有一个 ObservableCollection<BasicTask>,它数据绑定到 XAML 中的 ListView,其中 BasicTask 是我开发的一个简单类。

我的命令在 ViewModel 中作为属性实例化,并且数据绑定到(在本例中为)AppBarButton UI 元素的“命令”属性。该命令的作用是调用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 中的方法,因为我将 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>

TaskListsObservableCollection&lt;TaskList&gt; TaskListsTaskList类如下;

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 绑定到任务列表ObservableCollection 中选定TaskListItems 属性,第二个ListView 没有更新。 p>

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}"

对于这个问题的任何和所有帮助将不胜感激:)

【问题讨论】:

  • CommandManager 仅适用于 WPF。 WinRT 基本上在尽可能多的方面存在缺陷。
  • 我们可以查看您的列表视图的 XAML 以及您的视图模型代码的相关部分吗?
  • @BoltClock 我添加了 XAML。请注意有两个ListViews,第二个绑定到第一个ListView中选中项的Items属性。
  • 您正在绑定到 SelectedTaskList.Items 但 TaskList 类的 items 属性不是可观察的集合。因此,对该列表的更改不会在视图中更新

标签: c# mvvm uwp icommand


【解决方案1】:

在我的 ViewModel(它实现了 INotifyPropertyChanged)中,我有一个 ObservableCollection 数据绑定到 ListView 中 XAML

类任务列表 { 公共字符串标题 { 获取;放; } 公共字符串描述 { 获取;放; } 公共列表项 { 获取;放; } ... }

其实我注意到你在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查看我的可行样本

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-21
    • 2011-09-21
    • 2015-03-14
    • 1970-01-01
    • 1970-01-01
    • 2020-06-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多