我在我的程序中使用BusyIndicator,目的是在视图上显示忙碌指示符,而viewModel正在从数据库中加载数据。
*注意:在我添加背景工作者之前,一切都很完美。
我的程序以这种方式构建:
我的观点包含:
<NetworkUI:NetworkView
x:Name="networkControl"
NodesSource="{Binding Network.Nodes}"
ConnectionsSource="{Binding Path=Network.Connections}"
MouseDown="networkControl_MouseDown"
MouseUp="networkControl_MouseUp"
MouseMove="networkControl_MouseMove"
/>
Network.Nodes和Network.Connections是我的问题(我需要看到它们,我不会)
它们绑定到名为mainWindowViewModel的viewModel,这是从数据库获取数据的主要方法,名为ShowSystem:
public void ShowSystem(bool update)
{
List<String> interfacesForFlow = new List<String>();
#region CreateNetworkClasses
MethodInfo getInterfacesWithGuidToFlow = dbType.GetMethod("getInterfacesWithGuidToFlow");
#endregion
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
#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
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
}
#region addNodesToUi
//Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => ));
try
{
//Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => ));
Debug.WriteLine("Success creating new nodeViewModel");
}
catch (Exception ex)
{
logger.addMessage("Error in creating new nodeViewModel " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in creating new nodeViewModel " + ex.Message + " Inner: " + ex.InnerException.Message);
}
int width = 0;
int height = 0;
foreach (var system in MainNet.Systems)
{
Debug.WriteLine("inside Foreach in system: " + system.Name + " interface " + system.Interfaces.Count + " structs " + system.Structs.Count);
if (nodes == null)
Debug.WriteLine("FUUUCCKKKK!");
try
{
Debug.WriteLine("Before add node");
try
{
Debug.WriteLine("trying to add: " + system.Name + " " + system.InputNum + " " + system.OutputNum + " " + system.Interfaces.Count + " " + system.Enums.Count + " " + system.Structs.Count);
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))));
}
catch (Exception ex)
{
logger.addMessage("Error adding new node to list " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error adding new node to list " + ex.Message + " Inner: " + ex.InnerException.Message);
}
Debug.WriteLine("Success adding new node to list");
}
catch (Exception ex)
{
logger.addMessage("Error in adding new node to list " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in adding new node to list " + ex.Message + " Inner: " + ex.InnerException.Message);
}
width += 150;
if (width >= 700)
{
width = 0;
height += 100;
}
}
if (MainWindow.IsFlow)
{
Object[] getInterfacesWithGuidToFlowParam = new Object[1];
getInterfacesWithGuidToFlowParam[0] = MainWindow.GuidToFlow;
try
{
interfacesForFlow = (List<String>)getInterfacesWithGuidToFlow.Invoke(sqlDB, getInterfacesWithGuidToFlowParam);
Debug.WriteLine("Success getInterfacesWithGuidToFlow " + interfacesForFlow.Count);
}
catch (Exception ex)
{
logger.addMessage("Error in getInterfacesWithGuidToFlow : " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getInterfacesWithGuidToFlow : " + ex.Message + " Inner: " + ex.InnerException.Message);
}
}
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
{
Debug.WriteLine("out id = " + outId);
ConnectionViewModel connection = null;
try
{
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => connection = new ConnectionViewModel()));
Debug.Write("Success creating new ConnectionViewModel");
}
catch (Exception ex)
{
logger.addMessage("Error in creating new ConnectionViewModel " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in creating new ConnectionViewModel " + ex.Message + " Inner: " + ex.InnerException.Message);
}
Object[] getSystemNameParams = new Object[1];
getSystemNameParams[0] = outId;
string destSystemName = "";
try
{
destSystemName = (String)getSystemName.Invoke(sqlDB, getSystemNameParams);
}
catch (Exception ex)
{
logger.addMessage("Error in getSystemName: " + ex.Message + " Inner: " + ex.InnerException.Message);
Debug.WriteLine("Error in getSystemName: " + ex.Message + " Inner: " + ex.InnerException.Message);
}
NodeViewModel sourceItem = null;
NodeViewModel destItem = null;
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => sourceItem = nodes.Find(x => x.Name == system.Name)));
//int sourceId = nodes.FindIndex(sourceItem);
Debug.Write("Success creating new sourceItem");
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => destItem = nodes.Find(x => x.Name == destSystemName)));
Debug.Write("Success creating new destItem");
try
{
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => destItem.InputSystems.Add(sourceItem.Name)));
}
catch (Exception ex)
{
logger.addMessage("Error adding input system: " + ex.Message);
Debug.Write("Error adding input system: " + ex.Message);
}
try
{
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => sourceItem.OutputSystems.Add(destItem.Name)));
}
catch (Exception ex)
{
logger.addMessage("Error adding OutputSystems: " + ex.Message);
Debug.Write("Error adding OutputSystems: " + ex.Message);
}
Debug.Write("Success bah");
//int destId = nodes.FindIndex(destItem);
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => connection.SourceConnector = sourceItem.OutputConnectors[i++]));
Debug.Write("Success bah");
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => connection.DestConnector = destItem.InputConnectors[destItem.InputConnectors.Count - 1]));
Debug.Write("Success bah");
// 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)));
//Debug.Write("Success bah");
if (MainWindow.IsFlow)
{
Debug.WriteLine("inside IsFlow!");
foreach (var @interface in interfacesForFlow)
{
String[] systems = @interface.Split('_');
Debug.WriteLine("Flow from: " + systems[0] + " To " + systems[1]);
if(systems[0].Equals(sourceItem.Name) && systems[1].Equals(destItem.Name))
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => connection.Type = ConnectionViewModel.ConnectorType.FLOW));
}
}
}
}
}
#endregion
}
这个方法是从backgroundWorker DoWork方法中调用的,这些是所有backgroundWorker引用的:
public MainWindowViewModel()
{
//
// Create a network, the root of the view-model.
//
Network = new NetworkViewModel();
nodes = new List<NodeViewModel>();
//ShowSystem(false);
bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.RunWorkerAsync(false);
//create networkt according to classes created
}
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => this.IsBusy = false));
this.IsBusy = false;
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => OnPropertyChanged("Network")));
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
//Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => ));
this.BusyContent = "Please Wait...";
this.IsBusy = true;
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => ShowSystem((bool)e.Argument)));
}
答案 0 :(得分:1)
您尚未正确实施BackgroundWorker
,尽管我已经为您提供了一个链接,以了解如何在评论中实施该内容:
Progress Bar update from Background worker stalling
您甚至没有从ShowSystem
调用BackgroundWorker
方法,那么您希望如何获得任何数据?:
void bw_DoWork(object sender, DoWorkEventArgs e)
{
//You should only update UI properties from here using Dispatcher.CurrentDispatcher
this.BusyContent = "Please Wait...";
this.IsBusy = true;
Dispatcher.CurrentDispatcher.BeginInvoke((Action)(() => OnPropertyChanged("Network")));
//This runs on the background thread so this is where you do long running process
ShowSystem(false);
}
你显然还没有学会如何使用BackgroundWorker
,所以这就是你应该做的,而不是来到这里并提出重复的问题。我已经为您提供了一个正确实现BackgroundWorker
的示例的链接,您可以在MSDN的BackgroundWorker Class页面中找到另一个示例。
我相信这足以让你再次前进。
答案 1 :(得分:0)
使用调度程序,UI在UI线程中工作。有关详细信息,请参阅here。基本上,任何与UI控件有关的事情都需要调度到UI线程。
答案 2 :(得分:0)
您必须在doWork中调用主线程中的方法,该方法在单独的线程中运行才能更新UI。
我建议您查看.NET4及更高版本中提供的http://msdn.microsoft.com/en-us/library/dd460693(v=vs.110).aspx。 (具体看看任务)