如何在 MVVM WPF 中刷新 UI
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12691499/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I refresh the UI in MVVM WPF
提问by Ofir
My project is based on the MVVM pattern.
我的项目基于 MVVM 模式。
I have built a tree view that shows my file system. Each folder has a checkbox for selecting the current folder. The selection process is taking some time so, while the operation runs, there is a button which is disabled and at the end of the operation I`m enabling the button.
我已经构建了一个树视图来显示我的文件系统。每个文件夹都有一个用于选择当前文件夹的复选框。选择过程需要一些时间,所以在操作运行时,有一个按钮被禁用,在操作结束时我启用了该按钮。
My problem is that when the button gets "disabled" I see it immediately. However, when the button is going back to the enabled mode I must do some action (like mouse click) to see the button enabled.
我的问题是,当按钮被“禁用”时,我会立即看到它。但是,当按钮返回启用模式时,我必须执行一些操作(例如鼠标单击)才能看到按钮启用。
How can I make sure that the UI will be updated immediately after the button is enabled?
如何确保在启用按钮后立即更新 UI?
These are my buttons:
这些是我的按钮:
<Button Content="<- 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}" />
In my ViewModelI added this code:
在我的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");
}
}
}
The UI update happens just after I execute a mouse click or any keystroke.
UI 更新发生在我执行鼠标单击或任何击键之后。
This is the code of the action that is disabling and enabling the buttons:
这是禁用和启用按钮的操作代码:
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;
}
What can I do?
我能做什么?
回答by Aghilas Yakoub
You can adjust on your control Binding mode TwoWay
and define triggers with PropertyChanged
您可以调整您的控件 Binding mode TwoWay
并定义triggers with PropertyChanged
{Binding ElementName=.., Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}
回答by Ofir
OK I found a solution.
I tried everything without success and eventually I found this thread:
Refresh WPF Command
好的,我找到了解决方案。
我尝试了一切都没有成功,最终我找到了这个线程:
刷新 WPF 命令
I have used CommandManager.InvalidateRequerySuggested()
我用过了 CommandManager.InvalidateRequerySuggested()
And its works.
和它的作品。
Thanks for your help
谢谢你的帮助
回答by sfogle
Here's a code example of how you might set up your ViewModel with the INotifyPropertyChanged method of sending messages to update the UI:
下面是一个代码示例,说明如何使用 INotifyPropertyChanged 方法设置 ViewModel 以发送消息以更新 UI:
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
}