如何在MVVM WPF中刷新UI

9

我的项目基于MVVM模式。

我已经建立了一个树形视图,显示我的文件系统。每个文件夹都有一个复选框用于选择当前文件夹。由于选择过程需要一些时间,因此在操作运行时,有一个按钮被禁用,等到操作结束后我才启用该按钮。

我的问题是,当按钮被“禁用”时,我立即看到它。然而,当按钮回到启用模式时,我必须执行某些操作(如鼠标单击)才能看到按钮变成可用状态。

我该如何确保UI在按钮启用后立即更新?

这些是我的按钮:

<Button Content="&lt;- Back" Margin="5,0,5,0" Width="80" Height="25"
        IsEnabled="{Binding CanMoveToPreviousPage, UpdateSourceTrigger=PropertyChanged}" 
        Command="{Binding Path=NavigateBackCommand, IsAsync=True}" />

<Button Content="{Binding ButtonNextCaption}" Margin="5,0,5,0" Width="80" Height="25"
        IsEnabled="{Binding CanMoveToNextPage, UpdateSourceTrigger=PropertyChanged}" 
        Command="{Binding Path=NavigateNextCommand, IsAsync=True}" />

在我的ViewModel中,我添加了以下代码:
public bool CanMoveToNextPage
{
    get
    {
        return this.CurrentPage != null && this.CurrentPage.CanMoveNext;
    }
    set
    {
        if (CurrentPage != null)
        {
            this.CurrentPage.CanMoveNext = value;
            OnPropertyChanged("CanMoveToNextPage");
        }
    }
}

public bool CanMoveToPreviousPage
{
    get { return 0 < this.CurrentPageIndex && CurrentPage.CanMoveBack; }
    set
    {
        if (CurrentPage != null)
        {
            this.CurrentPage.CanMoveBack = value;
            OnPropertyChanged("CanMoveToPreviousPage");
        }
    }
}

当我执行鼠标点击或任何按键操作时,UI将会更新。

以下是禁用和启用按钮的操作代码:

void bg_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
    DecrementDoneCounter();
    if (ThreadSafeCouner == 0)//means all bg workers are done
    {
        UIlimitation(true);
    }
}

private int ThreadSafeCouner; // check how many bgworkers run
public void IncrementDoneCounter() { Interlocked.Increment(ref ThreadSafeCouner); }
public void DecrementDoneCounter() { Interlocked.Decrement(ref ThreadSafeCouner); }


void bg_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
    IncrementDoneCounter();
    UIlimitation(false);
    ((bgArguments)e.Argument).SelectedDirectory.CanSelected = false;
    MarkItems(((bgArguments)e.Argument).SelectedDirectory, ((bgArguments)e.Argument).IsSelect);
    ((bgArguments)e.Argument).FreeWorkerAllocation();
    ((bgArguments)e.Argument).SelectedDirectory.CanSelected = true;
}

//this is the enabling action which execute the propeties setters at the upper part of this post
private static void UIlimitation(bool limit)
{
    MainWindowViewModel.Instance.CanMoveToNextPage = limit;
    MainWindowViewModel.Instance.CanMoveToPreviousPage = limit;
}

我能做些什么呢?


1
尝试使用 this.UpdateLayout() 或 ButtonsParent.UpdateLayout()。 - Florian Gl
当您的操作完成后,是否为负责启用/禁用按钮的相关属性引发“OnPropertyChanged”事件? - Rohit Vats
当我完成后,我更改了启用属性,但Set{...}和Set{}包括OnPropertyChanged事件。当我尝试调试时,一切都完美地工作,按钮可以在没有单击的情况下启用。我可以找出问题所在。 - Ofir
我在触发事件时添加了代码。感谢您的帮助。 - Ofir
3个回答

6

您可以在控件上调整 绑定模式为TwoWay 并定义 使用PropertyChanged触发器

{Binding ElementName=.., Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}

我已经做了,但问题仍然存在。 - Ofir
MVVM模型应该实现INotifyPropertyChanged接口,以便向控件发送通知。 - Aghilas Yakoub

4

好的,我找到了一个解决方案。
我尝试了很多方法都没有成功,最终我找到了这个帖子:刷新WPF命令

我使用了CommandManager.InvalidateRequerySuggested()

它起作用了。

谢谢你的帮助。


3

以下是一个代码示例,展示了如何使用INotifyPropertyChanged方法来发送消息以更新UI,从而设置您的ViewModel:

public class MyViewModel : INotifyPropertyChanged
{
    /******************************************************/
    /* Property that you have created two-way binding for */
    /******************************************************/
    private double _myProperty
    public double MyProperty
    {
        get { return _myProperty; }
        set
        {
            _myProperty = value;

            OnNotifyPropertyChanged("MyProperty");
        }
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnNotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion INotifyPropertyChanged Members
}

确保OnNotifyPropertyChanged("MyProperty");的值正确。 - Sven van den Boogaart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接