3 Stimmen

Hinzufügen von Knoten zu TreeView verursacht Thread-Exception

Ich habe ein kleines Problem.

Ich habe eine Klasse erstellt, die meine Prefabs (vordefinierte Objekte für meinen Level-Editor) verwaltet. Beim Laden der Prefabs beim Start, erstellt es TreeNodes für Kategorien und jede Prefab und fügt es zu einem TreeView, die es durch den Konstruktor kennt.

Das Problem ist, dass jedes Mal, wenn es einen Knoten zu einem anderen Knoten hinzufügt, es eine "InvalidOperationException" verursacht, weil es nicht der richtige Thread ist. Ich sollte das Steuerelement aufrufen. Ich habe es versucht, und es ist der gleiche Thread - es ist nur in der "LoadForm"-Ereignis aufgerufen.

Hier ist mein Code der PrefabManager-Klasse :

        public PrefabManager(TreeView tree)
    {
        _tree = tree;
        _prefabs = new List<Prefab>();
    }

    public void LoadPrefabs()
    {
        if (!Directory.Exists(_prefabPath))
            Directory.CreateDirectory(_prefabPath);

        _tree.Nodes["RootNode"].Nodes.Clear();

        foreach (string file in Directory.GetFiles(_prefabPath, "*.pref", SearchOption.AllDirectories))
        {
            Prefab prefab = Prefab.Load(file);
            if (_prefabs.Count > 0)
                if (_prefabs.Where(pfab => pfab.CreationName == prefab.CreationName).FirstOrDefault() != null) continue;

            TreeNode categoryNode = GetCategoryOrCreate(prefab.Category);
            TreeNode prefabNode = new TreeNode(prefab.CreationName)
                                      {
                                          ImageIndex = 2,
                                          SelectedImageIndex = 2,
                                          Tag = "Prefab"
                                      };
            MessageBox.Show(System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());
            categoryNode.Nodes.Add(prefabNode);

            _prefabs.Add(prefab);
        }
    }

Und hier ist die Kreation und der Aufruf:

            _flagSystem.AddFlag("PrefabManager", new PrefabManager(tpage_prefabs_tree));
            //...
            _flagSystem.GetFlag<PrefabManager>("PrefabManager").LoadPrefabs();

Der Fehler wird hier verursacht:

//LoadPrefabs-Method:
categoryNode.Nodes.Add(prefabNode);

Wo liegt Ihrer Meinung nach das Problem? Ich kann nicht glauben, dass es sich um ein Thread-Problem handelt. Wie kann ich dieses Problem lösen?

Herzlichen Dank :)

EDITAR Schade, dass niemand eine Antwort weiß :( Übrigens, hier ist der Stacktrace und einige Informationen über die Ausnahme:

bei System.Windows.Forms.TreeNode.Realize(Boolean insertFirst)
bei System.Windows.Forms.TreeNodeCollection.AddInternal(TreeNode node, Int32 delta)
bei System.Windows.Forms.TreeNodeCollection.Add(TreeNode node)
bei GooEditor.Prefabs.PrefabManager.GetCategoryOrCreate(String category) in E:\Sicherung\Visual Studio 2008\Projects\BioHazard\GooEditor\Prefabs\PrefabManager.cs:Zeile 87.
bei GooEditor.Prefabs.PrefabManager.LoadPrefabs() in E:\Sicherung\Visual Studio 2008\Projects\BioHazard\GooEditor\Prefabs\PrefabManager.cs:Zeile 40.
bei GooEditor.EditorForm.LoadContent() in E:\Sicherung\Visual Studio 2008\Projects\BioHazard\GooEditor\EditorForm.cs:Zeile 202.
bei GooEditor.Editor.LoadContent() in E:\Sicherung\Visual Studio 2008\Projects\BioHazard\GooEditor\Editor.cs:Zeile 117.
bei Microsoft.Xna.Framework.Game.Initialize()
bei GooEngine.Core.Application.Initialize() in E:\Sicherung\Visual Studio 2008\Projects\BioHazard\GooEngine\Core\Application.cs:Zeile 85.
bei Microsoft.Xna.Framework.Game.RunGame(Boolean useBlockingRun)
bei Microsoft.Xna.Framework.Game.Run()
bei XNAViewer.XNAViewer.StartGameLoop(Object game)
bei System.Threading.ThreadHelper.ThreadStart_Context(Object state)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
bei System.Threading.ThreadHelper.ThreadStart(Object obj)

{"Der für dieses Steuerelement durchgeführte Vorgang wird vom falschen Thread aufgerufen. Marshallen Sie den richtigen Thread mit Control.Invoke oder Control.BeginInvoke, um den Vorgang auszuführen."}

( Übersetzung ) Der Test, der für diese Steuerungsoperation durchgeführt wird, wird von dem falschen Thread aufgerufen. Marschieren des richtigen Threads oder mit Control.Invoke Control.BeginInvoke, um die Operation durchzuführen

1voto

SharpShade Punkte 1592

Verzeihung. Jetzt habe ich die Lösung.

Ich habe es nur falsch aufgerufen - deshalb hat es nicht funktioniert. Hier habe ich etwas gefunden, das mir gezeigt hat, wie es funktioniert: Thread Control.Invoke

Hier das Beispiel:

  _tree.Invoke((MethodInvoker) (() => categoryNode.Nodes.Add(prefabNode)));

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X