WPF-Alternative zur FastColoredTextbox

  • WPF

Es gibt 47 Antworten in diesem Thema. Der letzte Beitrag () ist von MichaHo.

    BindingMode=TwoWay?

    Klappt das nicht? Ich kanns gerade nich probieren.
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hab ich schon eingestellt, funktioniert aber auch nicht.

    Wenn man sich überlegt: Wie soll denn überhaupt dieses Attaced Property etwas von der Änderung mitbekommen. Es ist ja nicht mit dem Text Property verbunden (dieses unterstützt ja kein Binding).
    Das einzige was das Attaced Property macht ist den Text bei Wertveränderung SETZEN.

    So sehe ich das mit meinem Kenntnisstand. Kläre mich ruhig auf, wenn ich einen Denkfehler drinne habe.

    Viele Grüße
    Florian
    Aber von meiner Logik her schon. Muss aber natürlich bei beiden gesetzt werden. Also bei beiden RTBs.

    Aber gerne probier ichs morgen mal aus.

    Grüße sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Huhu,
    ist ja witzig das 3 Leute gleichzeit ähnliche Programme machen :)
    Ich bin nebenher dabei, mein SnippsCode Programm von WinForms auf WPF umzustellen.
    Anders als bei dem WinForms Programm möchte ich beim neuen Programm mit Dateien arbeiten, nicht mit einem Datatset...
    Daher sind meine Anforderungen an AvalonEdit etwas einfacher....
    Ich habe in meinem ViewModel einfach eine neue TextEditor Instanc generiert, stelle dort die Properties ein. Im Xaml habe ich dann ein ContentControl welches ich an die TextEditor Instanz des ViewModel binde.
    Klappt super...

    XML-Quellcode

    1. <Grid>
    2. <TabControl>
    3. <TabItem>
    4. <ContentControl Content="{Binding CodeEditor}"/>
    5. </TabItem>
    6. </TabControl>
    7. </Grid>


    Das ViewModel:

    C#-Quellcode

    1. using MHoApps.Core.ViewModel;
    2. using ICSharpCode.AvalonEdit;
    3. using ICSharpCode.AvalonEdit.Highlighting;
    4. using ICSharpCode.AvalonEdit.Document;
    5. using System.IO;
    6. namespace MHoApps.SnippsCode.ViewModel
    7. {
    8. /// <summary>
    9. ///
    10. /// </summary>
    11. public class EditorViewModel : ViewModelBase
    12. {
    13. #region Private Properties
    14. private readonly TextEditor _codeEditor = new TextEditor();
    15. #endregion
    16. #region Constructor
    17. /// <summary>
    18. /// default constructor
    19. /// </summary>
    20. public EditorViewModel()
    21. {
    22. _codeEditor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinitionByExtension(Path.GetExtension(File)); ;
    23. _codeEditor.ShowLineNumbers = ShowLineNumbers;
    24. _codeEditor.Load(File);
    25. }
    26. #endregion
    27. #region Public Properties
    28. public string File { get; set; } = @"D:\AzureDevOps\MHoApps\Special\WindowViewModel.cs";
    29. public TextEditor CodeEditor => _codeEditor;
    30. public string SyntaxHighlighting { get; set; }
    31. public bool ShowLineNumbers { get; set; } = true;
    32. public string EditorText { get; set; }
    33. #endregion
    34. }
    35. }


    Das schöne daran ist, das AvalonEdit das SyntaxHighlighting anhand der File Extension erledigen kann...
    "Hier könnte Ihre Werbung stehen..."
    JA, ist mir auch schon aufgefallen. Ich sehe nur noch RTBs. :P

    MichaHo schrieb:

    Ich habe in meinem ViewModel einfach eine neue TextEditor Instanc generiert,

    Uhhhh. :S Ab hier ist es dann im Grunde kein ViewModel mehr. Entweder CodeBehind oder MVVM. Hier holst du dir die View ins ViewModel.

    Geht auch ohne, wie du gesehen hast kannst du ja ein AttachedPRoperty erstellen auf welches du Bindenkannst oder du erstellst dir ein UserControl und in deren CodeBehind reagierst du auf das Ereignis "DataContext_Changed" und holst dir das ViewModel in die CodeBehind und füllst die Avalon RTB. Fertich.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hi @Nofear23m jepp, so ist der Plan... (also ein UserControl) bin noch am testen wegen dem öffnen und speichern von files, daher erstmal das AvalonEdit im ViewModel.

    Bin gerade noch dabei zu erörtern, wie ich mehrere TabItems bzw. TabControls neben einander anzeige... hast Du da vielleicht ein einfaches Beispiel?
    "Hier könnte Ihre Werbung stehen..."

    MichaHo schrieb:

    wie ich mehrere TabItems bzw. TabControls neben einander anzeige

    Das musst du genauer eklären, aber besser in einem neuen Thread. ;)
    Denn.... die sind ja nebeneinander.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hallo,

    so ich habe mein Problem (mit dem Text Binding an den AvalonTextEditor) so weit gelöst. Allerdings bin ich mir sicher, dass das nicht ganz "WPFlike" ist:

    Im XAML setze ich jetzt einfach einen EventHandler auf das TextChanged Event, siehe:

    XML-Quellcode

    1. <Window x:Class="AvalonTextEditBindingHelper.MainWindow"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    5. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    6. xmlns:local="clr-namespace:AvalonTextEditBindingHelper"
    7. xmlns:avalon="http://icsharpcode.net/sharpdevelop/avalonedit"
    8. xmlns:vm="clr-namespace:AvalonTextEditBindingHelper"
    9. mc:Ignorable="d"
    10. Title="MainWindow" Height="450" Width="800">
    11. <Window.DataContext>
    12. <vm:MainViewModel/>
    13. </Window.DataContext>
    14. <Grid>
    15. <Grid.RowDefinitions>
    16. <RowDefinition Height="*"/>
    17. <RowDefinition Height="*"/>
    18. </Grid.RowDefinitions>
    19. <avalon:TextEditor vm:AvalonTextBindingHelper.AvalonText="{Binding Text, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" SyntaxHighlighting="C#"
    20. TextChanged="TextEditor_TextChanged">
    21. </avalon:TextEditor>
    22. <TextBox Grid.Row="1" Text="{Binding Text, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
    23. </TextBox>
    24. </Grid>
    25. </Window>


    Im CodeBehind fange ich dieses Event ab, und verarbeite es so:

    C#-Quellcode

    1. private void TextEditor_TextChanged(object sender, EventArgs e)
    2. {
    3. TextEditor t = (TextEditor)sender;
    4. AvalonTextBindingHelper.SetAvalonText(t, t.Text);
    5. }


    Die AvalonTextBindingHelper Klasse und das MainViewModel ist gleich wie im vorherigen Post, trozdem zur Übersicht hier noch einmal:

    MainViewModel

    C#-Quellcode

    1. public class MainViewModel : ViewModelBase
    2. {
    3. private string _Text;
    4. public string Text
    5. {
    6. get { return _Text; }
    7. set { _Text = value; RaisePropertyChanged(); }
    8. }
    9. public MainViewModel()
    10. {
    11. Text = "public in i = 0;";
    12. }
    13. }


    AvalonTextBindingHelper

    C#-Quellcode

    1. public class AvalonTextBindingHelper
    2. {
    3. public static string GetAvalonText(TextEditor obj)
    4. {
    5. return (string)obj.GetValue(AvalonTextProperty);
    6. }
    7. public static void SetAvalonText(TextEditor obj, string value)
    8. {
    9. obj.SetValue(AvalonTextProperty, value);
    10. }
    11. // Using a DependencyProperty as the backing store for AvalonText. This enables animation, styling, binding, etc...
    12. public static readonly DependencyProperty AvalonTextProperty =
    13. DependencyProperty.RegisterAttached("AvalonText", typeof(string), typeof(AvalonTextBindingHelper), new PropertyMetadata("", AvalonTextProperty_Changed));
    14. private static void AvalonTextProperty_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
    15. {
    16. TextEditor textEditor = (TextEditor)d;
    17. textEditor.Document.Text = e.NewValue.ToString();
    18. }
    19. }



    @Nofear23m Eventuell könntest du mir noch eine WPF konforme Lösung aufzeigen, wenn es da eine gibt.

    Viele Grüße
    Florian
    Hallo Florian

    Eine möglichkeit wäre im Grunde genau das was du über die CodeBehind gemacht hast in den Helper zu packen. Das hätte den Vorteil das es dort wiederverwendbar ist und somit immer funktioniert ohne das man daran denken muss in die CodeBehind was einzufügen.

    VB.NET-Quellcode

    1. Imports ICSharpCode.AvalonEdit
    2. Namespace XamlHeper
    3. Public Class AvalonTextBindingHelper
    4. Inherits DependencyObject
    5. Public Shared Function GetAvalonText(ByVal element As DependencyObject) As String
    6. If element Is Nothing Then
    7. Throw New ArgumentNullException("element")
    8. End If
    9. Return CType(element.GetValue(AvalonTextProperty), String)
    10. End Function
    11. Public Shared Sub SetAvalonText(ByVal element As DependencyObject, ByVal value As String)
    12. If element Is Nothing Then
    13. Throw New ArgumentNullException("element")
    14. End If
    15. element.SetValue(AvalonTextProperty, value)
    16. End Sub
    17. Public Shared ReadOnly AvalonTextProperty As _
    18. DependencyProperty = DependencyProperty.RegisterAttached("AvalonText",
    19. GetType(String), GetType(AvalonTextBindingHelper),
    20. New PropertyMetadata(Nothing, AddressOf AvalonTextProprty_Changed))
    21. Private Shared Sub AvalonTextProprty_Changed(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
    22. Dim textEditor As TextEditor = CType(d, TextEditor)
    23. RemoveHandler textEditor.TextChanged, AddressOf AvalonText_Changed
    24. AddHandler textEditor.TextChanged, AddressOf AvalonText_Changed
    25. textEditor.Document.Text = e.NewValue.ToString
    26. End Sub
    27. Private Shared Sub AvalonText_Changed(ByVal sender As Object, ByVal e As EventArgs)
    28. Dim av = DirectCast(sender, TextEditor)
    29. av.SetValue(AvalonTextProperty, av.Document.Text)
    30. End Sub
    31. End Class
    32. End Namespace


    XML-Quellcode

    1. <Window x:Class="MainWindow"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    5. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    6. xmlns:avalon="http://icsharpcode.net/sharpdevelop/avalonedit"
    7. xmlns:local="clr-namespace:AvalonDemo"
    8. xmlns:helper="clr-namespace:AvalonDemo.XamlHeper"
    9. mc:Ignorable="d"
    10. Title="MainWindow" Height="450" Width="800">
    11. <Window.DataContext>
    12. <local:DemoClass/>
    13. </Window.DataContext>
    14. <Grid>
    15. <Grid.RowDefinitions>
    16. <RowDefinition Height="*"/>
    17. <RowDefinition Height="*"/>
    18. </Grid.RowDefinitions>
    19. <avalon:TextEditor x:Name="myAvalon" ShowLineNumbers="True" helper:AvalonTextBindingHelper.AvalonText="{Binding MyTextPropInViewModel,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Grid.Row="0" Margin="5"/>
    20. <TextBox Text="{Binding MyTextPropInViewModel,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" x:Name="myTextBox" Grid.Row="1" Margin="5" TextWrapping="Wrap"/>
    21. </Grid>
    22. </Window>


    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hallo

    Um sicher zu gehen das es nur einen einzigen gibt.

    Da der Handler ja immer bei jeder Textänderung aufgerufen wird würde er dann beim 3. Buchstaben die Prozedur bereits 3x ausführen, beim 10. Buchstaben bereits 10x. Ich denke ab dem 20. Buchstaben wirds dann sicher sehr langsam. ;)

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Neu

    Nofear23m schrieb:

    erstellst dir ein UserControl und in deren CodeBehind reagierst du auf das Ereignis "DataContext_Changed"

    Hi Sascha,
    Dazu hab ich eine Frage.
    Ich hab erst mit der Attached Property gearbitet, benötige aber mehr zugriffe auf den TextEditor (zum ändern, speichern usw.) Daher komme ich nochmal auf das obige Zitat zurück.
    In meiner Anwendung gibt es einen TreeView, dieser ist eine Auflistung aller Ordner und Dateien in einem angegebenen Pfad. drücke ich auf eine Datei, öffnet sich ein Tabcontrol mit einer Tabpage und (so Gott will) einem TextEditor darin mit dem Inhalt der Datei.
    Es gibt 2 Viewodel für das TreeView (Einmal die Auflistung und einmal für das einzelne Item) für das Tabcontrol gibt es 3 View Model (einmal die Auflistung als Singelton, einmal das einzelne Item und einmal für den TextEditor selbst)
    Nun ist es ja so, das jedes UserControl sein eihgenens ViewModel hat, so auch das TextEditor UserControl
    das TabItemViewmodel hat eine Property EditorViewModel welches den TextEditro representiert.
    Wenn ich nun eine neue TabPage hinzufüge, muss ich ja eine Instanz des Editorviemodel erstellen.
    Im CodeBehind des UserControl muss ich aber ja auch ein neues ViewModel erstellen.... da dreht sich grad mein Kopf etwas...

    der Code für das Hinzufügen einer neuen TabPage:

    C#-Quellcode

    1. private void OpenFile()
    2. {
    3. if (Type != DirectoryItemTypeEnum.File)
    4. return;
    5. var newTab = new TabItemViewModel {Header = Name, Tag = FullPath, CodeEditor = new EditorViewModel(FullPath) };
    6. if (IoC.CodeEditor.Tabs.Any(h => h.Header == newTab.Header))
    7. {
    8. var existingTab = IoC.CodeEditor.Tabs.Single(h => h.Header == newTab.Header);
    9. IoC.CodeEditor.SelectedItem = existingTab;
    10. return;
    11. }
    12. IoC.CodeEditor.Tabs.Add(newTab);
    13. IoC.CodeEditor.SelectedItem = newTab;
    14. }


    das TabItemViewModel:
    Spoiler anzeigen

    C#-Quellcode

    1. public class TabItemViewModel : ViewModelBase
    2. {
    3. #region Constructor
    4. /// <summary>
    5. /// default constructor
    6. /// </summary>
    7. public TabItemViewModel()
    8. {
    9. CloseCommand = new RelayCommand(t => CloseTab());
    10. if (IsInDesignMode)
    11. {
    12. Header = "TestTab";
    13. }
    14. }
    15. #endregion
    16. public string Header { get; set; }
    17. public string Tag { get; set; }
    18. public EditorViewModel CodeEditor { get; set; }
    19. public ICommand CloseCommand { get; set; }
    20. private void CloseTab()
    21. {
    22. IoC.CodeEditor.Tabs.Remove(IoC.CodeEditor.Tabs.Where(t => t.Tag == Tag).Single());
    23. }
    24. }


    das EditorViewModel (noch nicht ganz fertig):
    Spoiler anzeigen

    C#-Quellcode

    1. public class EditorViewModel : ViewModelBase
    2. {
    3. #region Constructor
    4. /// <summary>
    5. /// default constructor
    6. /// </summary>
    7. public EditorViewModel()
    8. {
    9. }
    10. public EditorViewModel(string path)
    11. {
    12. TextPath = path;
    13. }
    14. #endregion
    15. public string Text { get; set; }
    16. public string TextPath { get; set; }
    17. public int TextLength { get; set; }
    18. }


    CodeBehind des UserControl:

    C#-Quellcode

    1. public partial class ucCodeEditor : UserControl
    2. {
    3. public ucCodeEditor()
    4. {
    5. InitializeComponent();
    6. }
    7. private void UserControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
    8. {
    9. EditorViewModel vm = new EditorViewModel(); //hier muss ich ja ein neues ViewModel erstellen, bekomme ja sonst keinen Zugriff drauf
    10. codeEditor.Load(vm.TextPath); // hier brauch ich den Pfad, um den Inhalt der Datei in den Editro zu laden
    11. DataContext = vm;
    12. }
    13. }


    Kannst Du mir da auf die Sprünge helfen?
    "Hier könnte Ihre Werbung stehen..."

    Neu

    MichaHo schrieb:

    benötige aber mehr zugriffe auf den TextEditor (zum ändern, speichern usw.)

    Warum das? Das sind alles Dinge die NICHT die View machen soll. Hat mit der View nix zu tun. Muss also ins ViewModel. Wenn du dein Text Property hast (AttachedProperty) hast du doch gar kein problem mehr mit speichern und der gleichen.

    MichaHo schrieb:

    einmal die Auflistung als Singelton

    Als Signleton? Bitte Leute, ich lese in letzter Zeit das viele mit Singleton-Klassen herumhantieren nur weil man glaubt das wäre die Lösung für alles. Ist es aber nicht. Eine Signleton sollte NUR im Notfall wenn es nicht anders geht erstellt werden. Ansonsten arbeitet bitte mit Instanzen.

    In deinem Fall wäre es wohl besser du lädst es mal hoch. Ich kann jetzt zwar versuchen dir hier zu helfen, aber wenn ich den Code korrigiere und hier als Snippets hochlade ist vermutlich so viel anders das man sich gar nicht mehr auskennt, ausserdem tu ich mir schwer hier im CodeTag C# zu korrigieren da es ja nicht meine Sprache ist.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Neu

    Hallo,

    ich melde mich auch noch mal kurz.

    Nofear23m schrieb:

    Als Signleton? Bitte Leute, ich lese in letzter Zeit das viele mit Singleton-Klassen herumhantieren nur weil man glaubt das wäre die Lösung für alles. Ist es aber nicht. Eine Signleton sollte NUR im Notfall wenn es nicht anders geht erstellt werden. Ansonsten arbeitet bitte mit Instanzen.

    Ich glaube du warst es sogar (Bitte auf keinen Fall als Vorwurf verstehen :) ), der mir damals zum Daten speichern eine Singleton Klasse empfohlen hatte. Um überall auf die Daten zuzugreifen und die gleiche Instanz zu haben.
    Ist dass doch nicht die optimale Lösung? Weil ich mache es jetzt immer so.

    Viele Grüße
    Florian

    Neu

    flori2212 schrieb:

    Ich glaube du warst es sogar

    Es kommt immer darauf an. Das muss man Fall für Fall entscheiden und sollte nur gemacht werden wenn es keine andere möglichkeit gibt da man sich mit Signleton-Klassen schnell mal ein Bein stellen kann.

    Aber...
    für das Tabcontrol gibt es 3 View Model (einmal die Auflistung als Singelton

    Ein ViewModel ist definitiv kein korrekter Einsatz für ein Singleton. Warum soll ich ein ViewModel als Signleton erstellen, ich kenne hierfür keinen Grund, aber wer weis, ich weis ja nicht genau was Micha vor hat, aber ich gehe mal davon aus des es nicht der richtige Ansatz ist und anders auch geht.


    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Neu

    Hi,
    Singleton deshalb, weil ich nur eine Instanz des Tabcontrol haben will um darin die entsprechenden TabPages hinzufügen oder entfernen will.
    Text ändern und zurück speichern funktioniert mit der Attched Property, aber zum Beispeil das Flag IsModified wüsste ich jetzt nicht wie ich das abfange um zum Beispiel im TabHeader den Button von x zu einem Punkt zu ändern, damit der User sieht das die Datei noch nicht gespeichert ist.

    Außerdem wirft mir das TextEditor eine Exception wenn ich das Tab schließe, weil der Text dann null ist.
    Ich baue mal ein Projekt mit dem Tree, dem Tabcontrol und dem AvalonEdit und lade es hoch.

    EDIT: Gerade noch die anderen Beiträge gelesen. Ich hab zum Beispiel auch ein ApplicationViewModel als Singelton (über den IoC Container) da ist zum Beispiel ein Property für den Pfad zum Standard SnippsCode Ordner, den Pfad hab ich dann in der ganzen Application zur Verfügung. Oder ein Property CodeExplorerVisible, das kann ich von überall aus auf true oder false setzen um dann ein Menü ein oder auszublenden...
    "Hier könnte Ihre Werbung stehen..."

    Neu

    MichaHo schrieb:

    Singleton deshalb, weil ich nur eine Instanz des Tabcontrol haben will


    Du hast ja ein ViewModel für dein Hauptfenster. Ich nenne es jetzt mal MainViewModel.
    In deinem MainViewModel ist ein Property - sagen wir mal EditorsList vom Typ ObservableCollection(Of EditorPageViewModel).

    Die Instanz von EditorsList gibt es also definitiv nur 1x. Wie soll es die denn auch mehrmals geben?

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Neu

    Hmmm dann steh ich auf dem Schlauch, wie komme ich denn dann vom, sagen wir mal, TreeViewItemViewModel an die EditorsList dran um zum Beispiel in einem Command ein neues Item zur EditorsList hinzuzufügen?
    "Hier könnte Ihre Werbung stehen..."

    Neu

    MichaHo schrieb:

    um zum Beispiel in einem Command ein neues Item zur EditorsList hinzuzufügen?

    Klingt nach murks. Warum soll ein TabItem ein weiteres hinzufügen? Sollte die Ebende darüber machen oder? Also das ViewModel wo die Auflistung drinnen ist findest du nicht.

    Aber wenn es sein muss kannst du ja dem TreeViewItemViewModel die Instanz von EditorsList im Konstrultor mitgeben und hast somit vom Item aus auf die Auflistung zugriff. Fertich.

    Grüße
    Sascha

    Edit: @MichaHo ich hoffe das ViewModel auf dem Screenshot in Post #24 kommt nicht zum einsatz. ;) Ein Window im ViewModel X/
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Nofear23m“ ()

    Neu

    Hi Sascha,
    Nee, den TextEditor hab ich komplett aus dem ViewModel raus genommen. Die TextProperty des Avalon Edit ist nun wieder an die Attached Property gebunden.

    ich bin mit den übergreifenden ViewModel etwas verwirrt. Eigentlich hat ja jede View ihr eigenes ViewModel, so hab ich das bei mir auch gemacht.
    es gibt links ein TreeView welches die Ordnerstruktur auflistet, dazu gibt es 2 ViewModel, das TreeViewListViewModel welches eine Liste von TreeViewItemViewModel hält und im Konstruktor des ListviewModel wird die Liste gefüllt.
    Im ItemViewModel werden die Dateien der Ordnerstruktur beim aufklappen der TreeViewItems nachgeladen, dazu hat das ItemViewModel eine Liste (ChildItems) von sich selbst.
    Dann hab ich rechts ein Tabcontrol, welches dann 3 ViewModel hat, nämlich einmal die Liste von TabItema, die TabItems selbst und ein extra ViewModel für den Avalon Edit um Propertys dran zu binden.
    Nun möchte ich, wenn ich auf ein TreeViewItem klickse, das dann eine neue TabPage zum TabControl hinzugefügt wird.
    Dazu, bin ich der Meinung, benötige ich genau 1 Instanz der TabControl Liste.

    wenn ich nun hergehe, wie du beschrieben hast, und meine TabControl Liste im MainViewModel halte, dann müsste ich ja diese Instanz bis runter zum TabItemViewModel durchreichen, richtig?

    oder wie komme ich dazu, im TreeViewItemViewModel beim Klicksen der Instanz ein Item hinzuzufügen?

    ich hab das gestern mal in einem neuen Projket nachgebaut, und es geht fast, sieht mir allerdings umständlich aus.
    ich lade das Projekt nachher mal hoch, bin gerade noch unterwegs.
    "Hier könnte Ihre Werbung stehen..."