WPF mvvm backgroundWorker busyIndicator
本文关键字:busyIndicator backgroundWorker mvvm WPF | 更新日期: 2023-09-27 18:01:55
我在使用MVVM模式的程序中使用busyIndicator,我发现后台工作人员和处理视图中绑定的对象存在问题,所以我使用了dispatcher。调用方法在所有使用绑定属性的函数上,在我使用dispatcher之后,busyIndicator出现了,但是当backgroundworker完成我的视图里面没有元素时,我做错了什么?
我知道代码有点低,但我不知道什么(如果)会有帮助,如果有必要,请让我知道,我会用所需的代码编辑此消息。
编辑:下面的代码可能会有所帮助:
这是创建BW,它发生在viewModel构造函数
bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.RunWorkerAsync(false);
是BW函数
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.IsBusy = false;
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
this.BusyContent = "Please Wait...";
this.IsBusy = true;
ShowSystem((bool)e.Argument);
}
showSystem方法很长所以我只添加使用UI元素的部分
List<NodeViewModel> nodes = null;
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => nodes = new List<NodeViewModel>()));
int width = 0;
int height = 0;
foreach (var system in MainNet.Systems)
{
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => nodes.Add(CreateNode(system.Name, new Point(width, height), false, system.InputNum, system.OutputNum, system.Interfaces, system.Enums, system.Structs, update))));
width += 150;
if (width >= 700)
{
width = 0;
height += 100;
}
}
if (MainWindow.IsFlow)
{
Object[] getInterfacesWithGuidToFlowParam = new Object[1];
getInterfacesWithGuidToFlowParam[0] = MainWindow.GuidToFlow;
interfacesForFlow = (List<String>)getInterfacesWithGuidToFlow.Invoke(sqlDB, getInterfacesWithGuidToFlowParam);
}
foreach (var system in MainNet.Systems)
{
if (system.OutputNum > 0) //this system has an output connector
{
int i = 0;
foreach (var outId in system.Outputs) //loop throw all systems ids that current system is connected to
{;
ConnectionViewModel connection = null;
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => connection = new ConnectionViewModel()));
Object[] getSystemNameParams = new Object[1];
getSystemNameParams[0] = outId;
string destSystemName = "";
destSystemName = (String)getSystemName.Invoke(sqlDB, getSystemNameParams);
NodeViewModel sourceItem = null;
NodeViewModel destItem = null;
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => sourceItem = nodes.Find(x => x.Name == system.Name)));
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => destItem = nodes.Find(x => x.Name == destSystemName)));
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => destItem.InputSystems.Add(sourceItem.Name)));
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => sourceItem.OutputSystems.Add(destItem.Name)));
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => connection.SourceConnector = sourceItem.OutputConnectors[i++]));
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => connection.DestConnector = destItem.InputConnectors[destItem.InputConnectors.Count - 1]));
// Add the connection to the view-model.
//
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => connection.Type = ConnectionViewModel.ConnectorType.REGULAR));
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => this.Network.Connections.Add(connection)));
if (MainWindow.IsFlow)
{
foreach (var @interface in interfacesForFlow)
{
String[] systems = @interface.Split('_');
if(systems[0].Equals(sourceItem.Name) && systems[1].Equals(destItem.Name))
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => connection.Type = ConnectionViewModel.ConnectorType.FLOW));
}
}
}
}
}
编辑:这是从数据库中获取数据的部分:
MainNet = Common.Model.Network.getNetwork();
Debug.WriteLine("MainNet.Systems.Count = " + MainNet.Systems.Count);
if (MainNet.Systems.Count == 0)
update = true;
List<String> systemNames = new List<string>();
if (update)
{
if(MainNet.Systems.Count > 0)
MainNet.Systems.Clear();
if (this.Network.Nodes.Count > 0)
{
this.Network.Nodes.Clear();
this.Network.Connections.Clear();
}
try
{
systemNames = (List<String>)getAllSystemMethod.Invoke(sqlDB, null);
Debug.WriteLine("Success getAllSystemMethod");
}
catch (Exception ex)
{
logger.addMessage("Error in getAllSystemMethod: " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getAllSystemMethod: " + ex.Message + " Inner: " + ex.InnerException.Message);
}
#region CreateSystems
foreach (var sysName in systemNames)
{
#region Intializating
ObservableCollection<Common.Model.Enum> enums = new ObservableCollection<Common.Model.Enum>();
ObservableCollection<Common.Model.Struct> structs = new ObservableCollection<Common.Model.Struct>();
ObservableCollection<Common.Model.Interface> interfaces = new ObservableCollection<Common.Model.Interface>();
//List<Model.Enum> enums = new List<Model.Enum>();
//List<Model.Struct> structs = new List<Model.Struct>();
//List<Model.Interface> interfaces = new List<Model.Interface>();
int systemId = -1;
Object[] getSystemIdParams = new Object[1];
getSystemIdParams[0] = sysName;
try
{
systemId = (int)getSystemId.Invoke(sqlDB, getSystemIdParams);
Debug.WriteLine("Success getSystemId systemId = " + systemId);
}
catch (Exception ex)
{
logger.addMessage("Error in getSystemId: " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getSystemId: " + ex.Message + " Inner: " + ex.InnerException.Message);
}
List<int> sysEnumsIds = new List<int>();
List<int> sysStructsIds = new List<int>();
List<int> sysInterfacesIds = new List<int>();
Object[] getSysEnumsIdParams = new Object[1];
getSysEnumsIdParams[0] = systemId;
try
{
sysEnumsIds = (List<int>)getSysEnumsId.Invoke(sqlDB, getSysEnumsIdParams); //return List<int> all system Enums ids
if (sysEnumsIds.Count > 0)
Debug.WriteLine("Success getSysEnumsId first count is " + sysEnumsIds.Count);
else
Debug.WriteLine("success getSysEnumsId but no ids found");
}
catch (Exception ex)
{
logger.addMessage("Error in getSysEnumsId: " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getSysEnumsId: " + ex.Message + " Inner: " + ex.InnerException.Message);
}
Object[] getSysStructsIdParams = new Object[1];
getSysStructsIdParams[0] = systemId;
try
{
sysStructsIds = (List<int>)getSysStructsId.Invoke(sqlDB, getSysStructsIdParams);
if (sysStructsIds.Count > 0)
Debug.WriteLine("success getSysStructsId count = " + sysStructsIds.Count);
else
Debug.WriteLine("success getSysStructsId but no ids found");
}
catch (Exception ex)
{
logger.addMessage("Error in getSysStructsId: " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getSysStructsId: " + ex.Message + " Inner: " + ex.InnerException.Message);
}
Object[] getSysInterfacesIdParams = new Object[1];
getSysInterfacesIdParams[0] = systemId;
try
{
sysInterfacesIds = (List<int>)getSysInterfacesId.Invoke(sqlDB, getSysInterfacesIdParams);
if (sysInterfacesIds.Count > 0)
Debug.WriteLine("Success getSysInterfacesId count = " + sysInterfacesIds.Count);
else
Debug.WriteLine("success getSysInterfacesId but no ids found");
}
catch (Exception ex)
{
logger.addMessage("Error in getSysInterfacesId: " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getSysInterfacesId: " + ex.Message + " Inner: " + ex.InnerException.Message);
}
#endregion
Object[] getStructFromIdParam = new Object[1];
getStructFromIdParam[0] = @struct;
List<Object> tempStruct = new List<object>();
try
{
tempStruct = (List<Object>)getStructFromId.Invoke(sqlDB, getStructFromIdParam);
Debug.WriteLine("Success getStructFromId " + tempStruct.Count);
}
catch (Exception ex)
{
logger.addMessage("Error in getStructFromIdParam : " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getStructFromIdParam : " + ex.Message + " Inner: " + ex.InnerException.Message);
}
structs.Add(new Common.Model.Struct(Convert.ToString(tempStruct[0]), Convert.ToString(tempStruct[1]), Convert.ToString(tempStruct[2]), fields, bitFields));
Debug.WriteLine("Success adding new struct: " + structs.Last().Name);
}
#endregion
#region GetInterfaces
foreach (var @interface in sysInterfacesIds) //get interface
{
ObservableCollection<Common.Model.Message> messages = new ObservableCollection<Common.Model.Message>();
ObservableCollection<Common.Model.Definition> definitions = new ObservableCollection<Common.Model.Definition>();
ObservableCollection<Common.Model.Include> includes = new ObservableCollection<Common.Model.Include>();
List<int> includesIds = new List<int>();
List<int> definitionsIds = new List<int>();
List<int> messagesIds = new List<int>();
#region getIncludes
Object[] getIncludesIdsParams = new object[1];
getIncludesIdsParams[0] = @interface;
try
{
includesIds = (List<int>)getIncludesIds.Invoke(sqlDB, getIncludesIdsParams);
Debug.WriteLine("Success getIncludesIds " + includesIds.Count);
}
catch (Exception ex)
{
logger.addMessage("Error in getIncludesIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getIncludesIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
}
foreach (var id in includesIds)
{
Object[] getIncludeParams = new object[1];
getIncludeParams[0] = id;
string includeName = "";
try
{
includeName = (string)getInclude.Invoke(sqlDB, getIncludeParams);
Debug.WriteLine("Success get include name = " + includeName);
}
catch (Exception ex)
{
logger.addMessage("Error in getInclude " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getInclude " + ex.Message + " Inner: " + ex.InnerException.Message);
}
includes.Add(new Common.Model.Include(includeName));
}
#endregion
#region getdefinitions
Object[] getdefinitionsIdsParams = new object[1];
getdefinitionsIdsParams[0] = @interface;
try
{
definitionsIds = (List<int>)getDefinitionsIds.Invoke(sqlDB, getdefinitionsIdsParams);
Debug.WriteLine("Success getDefinitionsIds " + definitionsIds.Count);
}
catch (Exception ex)
{
logger.addMessage("Error in getDefinitionsIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getDefinitionsIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
}
foreach (var id in definitionsIds)
{
List<Object> definition = new List<object>();
Object[] getDefinitionParams = new object[1];
getDefinitionParams[0] = id;
string includeName = "";
try
{
definition = (List<Object>)getDefinition.Invoke(sqlDB, getDefinitionParams);
Debug.WriteLine("Success getDefinisions " + definition[0]);
}
catch (Exception ex)
{
logger.addMessage("Error in getInclude " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getInclude " + ex.Message + " Inner: " + ex.InnerException.Message);
}
definitions.Add(new Common.Model.Definition(Convert.ToString(definition[0]), Convert.ToInt32(definition[1])));
}
#endregion
#region getMessages
Object[] getMessagesIdsParams = new object[1];
getMessagesIdsParams[0] = @interface;
Debug.WriteLine("Trying to get messages for interface #" + @interface);
try
{
messagesIds = (List<int>)getMessagesIds.Invoke(sqlDB, getMessagesIdsParams);
Debug.WriteLine("Success getMessagesIds " + messagesIds.Count);
}
catch (Exception ex)
{
logger.addMessage("Error in getMessagesIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getMessagesIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
}
foreach (var id in messagesIds)
{
//List<Model.MType> types = new List<Model.MType>();
ObservableCollection<Common.Model.MType> types = new ObservableCollection<Common.Model.MType>();
List<int> typesIds = new List<int>();
Object[] getMessageTypesIdsParams = new Object[1];
getMessageTypesIdsParams[0] = id;
try
{
typesIds = (List<int>)getMessageTypesIds.Invoke(sqlDB, getMessageTypesIdsParams);
Debug.WriteLine("Success getMessageTypesIds " + typesIds.Count);
}
catch (Exception ex)
{
logger.addMessage("Error in getMessageTypesIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getMessageTypesIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
}
foreach (var typeId in typesIds)
{
List<Object> type = new List<object>();
Object[] getTypeParams = new object[1];
getTypeParams[0] = typeId;
//string includeName = "";
try
{
type = (List<Object>)getType.Invoke(sqlDB, getTypeParams);
Debug.WriteLine("Success getType");
}
catch (Exception ex)
{
logger.addMessage("Error in getType " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getType " + ex.Message + " Inner: " + ex.InnerException.Message);
}
types.Add(new Common.Model.MType((string)type[0], (string)type[1], (string)type[2], (string)type[3], (string)type[4], (string)type[5], (Guid)type[6]));
Debug.WriteLine("Success adding new type: " + (string)type[0] + " " + (string)type[1] + " " + (string)type[2] + " " + (string)type[3] + " " + (string)type[4] + " " + (string)type[5] + " " + (Guid)type[6]);
}
string sourceSystem = "";
string destSystem = "";
List<Object> message = new List<object>();
Object[] getMessageParams = new Object[1];
getMessageParams[0] = id;
try
{
message = (List<Object>)getMessage.Invoke(sqlDB, getMessageParams);
Debug.WriteLine("Success getMessageParams");
}
catch (Exception ex)
{
logger.addMessage("Error in getMessageTypesIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getMessageTypesIds: " + ex.Message + " Inner: " + ex.InnerException.Message);
}
messages.Add(new Common.Model.Message(types, message[0].ToString(), (int)message[1], message[2].ToString(), message[3].ToString(), message[4].ToString(), message[5].ToString(), message[6].ToString(), message[7].ToString(), message[8].ToString(), message[9].ToString()));
Debug.WriteLine("Success adding new Message: " + message[0].ToString() + " " + (int)message[1] + " " + message[2].ToString() + " " + message[3].ToString() + " " + message[4].ToString() + " " + message[5].ToString() + " " + message[6].ToString() + " " + message[7].ToString() + " " + message[8].ToString() + " " + message[9].ToString());
}
#endregion
Object[] getInterfaceFromIdParam = new Object[1];
getInterfaceFromIdParam[0] = @interface;
List<Object> tempInterface = new List<object>();
try
{
tempInterface = (List<Object>)getInterfaceFromId.Invoke(sqlDB, getInterfaceFromIdParam);
Debug.WriteLine("Success getInterfaceFromId " + tempInterface.Count);
}
catch (Exception ex)
{
logger.addMessage("Error in getInterfaceFromId : " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getInterfaceFromId : " + ex.Message + " Inner: " + ex.InnerException.Message);
}
interfaces.Add(new Common.Model.Interface(messages, definitions, includes, Convert.ToString(tempInterface[0]), Convert.ToString(tempInterface[1]), Convert.ToInt32(tempInterface[2]), Convert.ToInt32(tempInterface[3]), Convert.ToBoolean(tempInterface[4])));
Debug.WriteLine("Success adding new interface: " + interfaces.Last().Name);
}
#endregion
#region InputOutputNumber
List<int> inputs = new List<int>();
List<int> outputs = new List<int>();
int inputCount = 0;
int outputCount = 0;
Object[] getSysInputNumParams = new Object[1];
getSysInputNumParams[0] = systemId;
try
{
inputs = (List<int>)getSysInputs.Invoke(sqlDB, getSysInputNumParams);
if (inputs != null)
{
inputCount = inputs.Count;
Debug.WriteLine("Success getSysInputNum inputs = " + inputCount);
}
else
Debug.WriteLine("Success getSysInputNum inputs = 0");
}
catch (Exception ex)
{
logger.addMessage("Error in getSysInputNum: " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getSysInputNum: " + ex.Message + " Inner: " + ex.InnerException.Message);
}
Object[] getSysOutputNumParams = new Object[1];
getSysOutputNumParams[0] = systemId;
try
{
outputs = (List<int>)getSysOutputs.Invoke(sqlDB, getSysOutputNumParams);
if (outputs != null)
{
outputCount = outputs.Count;
Debug.WriteLine("Success getSysOutputNum outputs = " + outputCount);
}
else
Debug.WriteLine("Success getSysOutputNum outputs = 0");
}
catch (Exception ex)
{
logger.addMessage("Error in getSysOutputNum: " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getSysOutputNum: " + ex.Message + " Inner: " + ex.InnerException.Message);
}
#endregion
Common.Model.System system = null;
try
{
system = new Common.Model.System(interfaces, enums, structs, sysName, inputCount, outputCount, inputs, outputs);
Debug.WriteLine("Success adding new system");
}
catch (Exception ex)
{
logger.addMessage("Error in creating new system: " + ex.Message);
Debug.WriteLine("Error in creating new system: " + ex.Message);
}
MainNet.Systems.Add(system);
Debug.WriteLine("Done! you now have a new system with: " + interfaces.Count + " interfaces And " + enums.Count + " Enums and " + structs.Count + " Structs, The name is: " + sysName + " numOfInput: " + inputCount + " numOfOutput: " + outputCount);
#endregion
}
#endregion
调度程序在这里被错误地使用
Dispatcher可以用来将代码封送到UI线程上,如果需要的话,可以指定优先级。代码不会立即执行并返回,而是按照DispatcherPriority顺序指定的优先级运行。
基本上你的代码说的是
- 创建列表
- >>排队代码,稍后在UI线程上填充列表
- 如果list不为空,执行一些代码
列表将始终为空,因为填充它的代码尚未运行。它只在可用时排队运行一次。
正确的方法是在后台工作线程中填充数据,然后将结果封送回UI线程以填充UI。
注意对象只能在创建它们的线程上被修改。因此,如果你有一些对象,你计划使用和/或修改UI后,你应该看到这样的东西:
- 启动BackgroundWorker获取数据
- BackgroundWorker获取后台线程的数据而不锁定UI
- BackgroundWorker完成并使用Dispatcher在UI线程上运行代码,该代码将更新第一步创建的对象,结果