Silverlight入门系列应用MVVM模式10BackgroundWorkder和MVVM.docx

上传人:b****2 文档编号:24523232 上传时间:2023-05-28 格式:DOCX 页数:12 大小:143.24KB
下载 相关 举报
Silverlight入门系列应用MVVM模式10BackgroundWorkder和MVVM.docx_第1页
第1页 / 共12页
Silverlight入门系列应用MVVM模式10BackgroundWorkder和MVVM.docx_第2页
第2页 / 共12页
Silverlight入门系列应用MVVM模式10BackgroundWorkder和MVVM.docx_第3页
第3页 / 共12页
Silverlight入门系列应用MVVM模式10BackgroundWorkder和MVVM.docx_第4页
第4页 / 共12页
Silverlight入门系列应用MVVM模式10BackgroundWorkder和MVVM.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

Silverlight入门系列应用MVVM模式10BackgroundWorkder和MVVM.docx

《Silverlight入门系列应用MVVM模式10BackgroundWorkder和MVVM.docx》由会员分享,可在线阅读,更多相关《Silverlight入门系列应用MVVM模式10BackgroundWorkder和MVVM.docx(12页珍藏版)》请在冰豆网上搜索。

Silverlight入门系列应用MVVM模式10BackgroundWorkder和MVVM.docx

Silverlight入门系列应用MVVM模式10BackgroundWorkder和MVVM

Silverlight下这个BackgroundWorker我们应当很熟悉了,以前在WinForms下面就有;当我们需要在当前UI线程之外的线程处理耗时的操作而不阻塞UI线程,就可以用这个BackgroundWorker.用起来也是很方便,需要注意的是在DoWork事件中不要操作UI线程的内容,把UI操作都放到ReportProgress事件处理和WorkCompleted事件处理中。

记住这两点就可以了。

今天讲的是Silverlight如何在MVVM模式下用BackgroundWorker。

总体原则就是把后台耗时业务处理和界面逻辑分开,既实现多线程,又实现界面和逻辑分离。

  

  主要BackgroundWorker代码:

  

  ViewModel代码:

(里面有个Command启动耗时任务,任务中ReportProgress事件处理和WorkCompleted事件通知UI)

1:

usingSystem;

2:

usingSystem.ComponentModel;

3:

usingSystem.Windows.Input;

4:

5:

namespaceBackgroundWorkerTest

6:

{

7:

publicclassViewModel:

INotifyPropertyChanged

8:

{

9:

publicICommandStartTaskCommand{get;privateset;}

10:

privateint_counter=0;

11:

12:

publicViewModel()

13:

{

14:

StartTaskCommand=newDelegateCommand(StartTask,CanStartTask);

15:

}

16:

17:

privatevoidStartTask(objectparam)

18:

{

19:

varbackgroundWorker=newBackgroundWorker();

20:

21:

backgroundWorker.WorkerSupportsCancellation=true;

22:

backgroundWorker.WorkerReportsProgress=true;

23:

24:

backgroundWorker.DoWork+=(s,e)=>

25:

{

26:

for(inti=0;i<10;i++)

27:

{

28:

System.Threading.Thread.Sleep(1000);

29:

_counter++;

30:

31:

backgroundWorker.ReportProgress(i*10,string.Format("ExecutetoNo.{0}",_counter.ToString()));

32:

}

33:

};

34:

35:

backgroundWorker.ProgressChanged+=(s,e)=>

36:

{

37:

CurrentProgress=e.ProgressPercentage;

38:

CurrentProgressText=e.UserState!

=null?

e.UserState.ToString():

String.Empty;

39:

};

40:

41:

backgroundWorker.RunWorkerCompleted+=(s,e)=>

42:

{

43:

CurrentProgress=100;

44:

CurrentProgressText="Completed!

";

45:

};

46:

47:

backgroundWorker.RunWorkerAsync();

48:

49:

}

50:

51:

privateboolCanStartTask(objectparam)

52:

{

53:

returntrue;

54:

}

55:

56:

privatestring_currentProgressText;

57:

publicstringCurrentProgressText

58:

{

59:

get{return_currentProgressText;}

60:

set

61:

{

62:

if(_currentProgressText!

=value)

63:

{

64:

_currentProgressText=value;

65:

66:

if(PropertyChanged!

=null)

67:

{

68:

PropertyChanged(this,newPropertyChangedEventArgs("CurrentProgressText"));

69:

}

70:

}

71:

}

72:

}

73:

74:

privatedouble_currentProgress;

75:

publicdoubleCurrentProgress

76:

{

77:

get{return_currentProgress;}

78:

set

79:

{

80:

if(_currentProgress!

=value)

81:

{

82:

_currentProgress=value;

83:

84:

if(PropertyChanged!

=null)

85:

{

86:

PropertyChanged(this,newPropertyChangedEventArgs("CurrentProgress"));

87:

}

88:

}

89:

}

90:

}

91:

92:

publiceventPropertyChangedEventHandlerPropertyChanged;

93:

94:

}

95:

96:

publicclassDelegateCommand:

ICommand

97:

{

98:

99:

///

100:

101:

///Occurswhenchangesoccurthataffectwhetherthecommandshouldexecute.

102:

103:

///

104:

105:

publiceventEventHandlerCanExecuteChanged;

106:

107:

108:

109:

FunccanExecute;

110:

111:

ActionexecuteAction;

112:

113:

boolcanExecuteCache;

114:

115:

116:

117:

///

118:

119:

///Initializesanewinstanceoftheclass.

120:

121:

///

122:

123:

///Theexecuteaction.

124:

125:

///Thecanexecute.

126:

127:

publicDelegateCommand(ActionexecuteAction,

128:

129:

FunccanExecute)

130:

{

131:

132:

this.executeAction=executeAction;

133:

134:

this.canExecute=canExecute;

135:

136:

}

137:

138:

139:

140:

#regionICommandMembers

141:

142:

///

143:

144:

///Definesthemethodthatdetermineswhetherthecommand

145:

146:

///canexecuteinitscurrentstate.

147:

148:

///

149:

150:

///

151:

152:

///Datausedbythecommand.

153:

154:

///Ifthecommanddoesnotrequiredatatobepassed,

155:

156:

///thisobjectcanbesettonull.

157:

158:

///

159:

160:

///

161:

162:

///trueifthiscommandcanbeexecuted;otherwise,false.

163:

164:

///

165:

166:

publicboolCanExecute(objectparameter)

167:

{

168:

169:

booltempCanExecute=canExecute(parameter);

170:

171:

172:

173:

if(canExecuteCache!

=tempCanExecute)

174:

{

175:

176:

canExecuteCache=tempCanExecute;

177:

178:

if(CanExecuteChanged!

=null)

179:

{

180:

181:

CanExecuteChanged(this,newEventArgs());

182:

183:

}

184:

185:

}

186:

187:

188:

189:

returncanExecuteCache;

190:

191:

}

192:

193:

194:

195:

///

196:

197:

///Definesthemethodtobecalledwhenthecommandisinvoked.

198:

199:

///

200:

201:

///

202:

203:

///Datausedbythecommand.

204:

205:

///Ifthecommanddoesnotrequiredatatobepassed,

206:

207:

///thisobjectcanbesettonull.

208:

209:

///

210:

211:

publicvoidExecute(objectparameter)

212:

{

213:

214:

executeAction(parameter);

215:

216:

}

217:

218:

#endregion

219:

220:

}

221:

}

  View(Xaml.cs)代码:

1:

usingSystem.Windows.Controls;

2:

3:

namespaceBackgroundWorkerTest

4:

{

5:

publicpartialclassMainPage:

UserControl

6:

{

7:

publicMainPage()

8:

{

9:

InitializeComponent();

10:

11:

this.DataContext=newViewModel();

12:

}

13:

}

14:

}

  View(Xaml)代码:

1:

Class="BackgroundWorkerTest.MainPage"

2:

xmlns="

3:

xmlns:

x="

4:

xmlns:

d="

5:

xmlns:

mc="http:

//schemas.openxmlformats.org/markup-compatibility/2006"

6:

mc:

Ignorable="d"

7:

d:

DesignHeight="300"d:

DesignWidth="400">

8:

9:

Name="LayoutRoot"Background="White">

10:

VerticalAlignment="Top"Width="87"Command="{BindingStartTaskCommand}"/>

11:

Text="{BindingCurrentProgressText}"VerticalAlignment="Top"Width="359"/>

12:

Margin="18,75,0,0"Name="progressBar1"VerticalAlignment="Top"Width="361"/>

13:

14:

  Dispatcher

  如果没有使用BackgroundWorker在非UI线程需要调用UI回调的时候,需要调用当前Application的Dispatcher来完成,比如:

1:

privatevoidUpdateUI()

2:

{

3:

Dispatcher.BeginInvoke(()=>

4:

{

5:

ProgressBar.Value=50;

6:

});

7:

}

  如果你在一个Class里面(非UserControl),也就是无法获得Application对象的情况下,情况要负责一些,你可以使用一个假的控件对象来构造一个Dummy控件,例如:

1:

//以下代码在非UserControl的Class里面:

2:

TextBlock_dispatcherObject=newTextBlock();

3:

privatevoidUpdateUINasty()//avoidthisapproachunlessit'sallyou'vegot

4:

{

5:

_dispatcherObject.Dispatcher.BeginInvoke(()=>

6:

{

7:

SomePage.ProgressBar.Value=50;

8:

});

9:

}

  反之,如果运行在UI线程里面,就不必像上面那样做,最好使用Deployment.Current.Dispatcher对象:

1:

privatevoidUpdateUINotSoNasty()

2:

{

3:

Deployment.Current.Dispatcher.BeginInvoke(()=>

4:

{

5:

SomePage.ProgressBar.Value=50;

6:

});

7:

}

  当然,最保险的方法是先检查当前线程是否是UI线程,如果不是,那么进行UI操作需要用BeginInvoke:

1:

Actionmyaction=()=>DoSomething();

2:

vardispatch=Deployment.Current.Dispatcher;

3:

if(dispatch.CheckedAccess)

4:

{

5:

myaction();

6:

}

7:

else

8:

{

9:

dispatch.BeginInvoke(myaction());

10:

}

  代码截图:

  

  使用定时器:

DispatcherTimer

1:

privatevoidStartTimer()

2:

{

3:

DispatcherTimertimer=newDispatcherTimer();

4:

5:

timer.Tick+=(s,e)=>

6:

{

7:

//dosomeveryquickworkhere

8:

9:

//updatetheUI

10:

StatusText.Text=DateTime.Now.Second.ToString();

11:

};

12:

13:

timer.Interval=TimeSpan.FromSeconds

(1);

14:

timer.Start();

15:

}

展开阅读全文
相关搜索

当前位置:首页 > 自然科学 > 数学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1