Laden...

Avalondock: SelectTemplate() wird nicht für das Element in AnchorablesSource aufgerufen

Erstellt von schnei01 vor 4 Jahren Letzter Beitrag vor 4 Jahren 1.174 Views
S
schnei01 Themenstarter:in
2 Beiträge seit 2019
vor 4 Jahren
Avalondock: SelectTemplate() wird nicht für das Element in AnchorablesSource aufgerufen

Hallo,
avalondock (XCeed.Wpf.Toolkit v3.5) : DockingManager.LayoutItemTemplateSelector.SelectTemplate() wird nicht für das Element in DockingManager.AnchorablesSource aufgerufen.

Um das Problem zu vereinfachen, habe ich ohne weitere Bearbeitung zwei UserControls (ViewDocumentControl und ViewToolControl ) sowie zwei Modelviewer (ModelViewerDoc und ModelViewerTool) erzeugt.


    /// <summary>
    /// Dokument-Model
    /// </summary>
    public class ModelViewerDoc {
        public string Title { get { return "Document"; } }
        public string ContentId { get { return "DOC_1"; } }
    }
    
    /// <summary>
    /// Tool-Model
    /// </summary>
    public class ModelViewerTool {
        public string Title { get { return "Tool"; } }
        public string ContentId { get { return "TOOL_1"; } }
    }


Ein weiterer Modelviewer ModelViewerMainWindow erzeugt das Model und dient als DataContext für das Hauptfenster.


    /// <summary>
    /// Generierung der Modelle
    /// </summary>
    public class ModelViewerMainWindow {

        public BindingList<ModelViewerTool> Tools { get; set; }
        public BindingList<ModelViewerDoc> Docs { get; set; }

        public ModelViewerMainWindow() {
            Tools = new BindingList<ModelViewerTool>();
            Docs = new BindingList<ModelViewerDoc>();

            Tools.Add(new ModelViewerTool());
            Docs.Add(new ModelViewerDoc());

        }
    }

Das Hauptfenster bindet die Instanz von ModelViewerMainWindow als statische Resource ein und übergibt diese den DockManger von avalondock als DataContext. Die beiden Listen des Modelviewers werden an die entsprechenden Eigenschaften des Dockmanagers gebunden. Mittels DataTemplateSelector und StyleSelector wird den Dockmanager die Zuordnung der visuellen Eigenschaften mitgeteilt.


   <Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:avalonDock="http://schemas.xceed.com/wpf/xaml/avalondock"
        xmlns:local="clr-namespace:WpfApp1"
        xmlns:viewer="clr-namespace:WpfApp1.Viewer"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <local:ModelViewerMainWindow x:Key="_MVMainWnd" />
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <avalonDock:DockingManager x:Name="dockManager" 
                                   DataContext="{StaticResource  ResourceKey=_MVMainWnd}"        
                                   AnchorablesSource="{Binding Tools}"
                                   DocumentsSource="{Binding Docs}"
                                   Grid.Row="0" Grid.Column="0" >
            
            <avalonDock:DockingManager.Theme>
                <avalonDock:AeroTheme/>
            </avalonDock:DockingManager.Theme>

            <avalonDock:DockingManager.LayoutItemTemplateSelector>
                <local:PanesTemplateSelector>

                    <local:PanesTemplateSelector.ViewDocTemplate>
                        <DataTemplate>
                            <viewer:ViewDocumentControl />
                        </DataTemplate>
                    </local:PanesTemplateSelector.ViewDocTemplate>
                    
                    <local:PanesTemplateSelector.ViewToolTemplate>
                        <DataTemplate>
                            <viewer:ViewToolControl />
                        </DataTemplate>
                    </local:PanesTemplateSelector.ViewToolTemplate>
                    
                </local:PanesTemplateSelector>

            </avalonDock:DockingManager.LayoutItemTemplateSelector>

            <avalonDock:DockingManager.LayoutItemContainerStyleSelector>
                <local:PanesStyleSelector>
                    <local:PanesStyleSelector.DocStyle>
                        <Style TargetType="{x:Type avalonDock:LayoutItem}">
                            <Setter Property="Title" Value="{Binding Model.Title}"/>
                            <Setter Property="ContentId" Value="{Binding Model.ContentId}"/>
                            <Setter Property="Visibility" Value="Visible"/>
                            <Setter Property="CanClose" Value="False"/>

                        </Style>
                    </local:PanesStyleSelector.DocStyle>

                    <local:PanesStyleSelector.ToolStyle>
                        <Style TargetType="{x:Type avalonDock:LayoutAnchorableItem}">
                            <Setter Property="Title" Value="{Binding Model.Title}"/>
                            <Setter Property="ContentId" Value="{Binding Model.ContentId}"/>
                            <Setter Property="Visibility" Value="Visible"/>
                            <Setter Property="CanClose" Value="False"/>
                        </Style>
                    </local:PanesStyleSelector.ToolStyle>
                    
                </local:PanesStyleSelector>
            </avalonDock:DockingManager.LayoutItemContainerStyleSelector>


        </avalonDock:DockingManager>
    </Grid>
</Window>

Die im xaml File enthaltenden Selektoren sind wie folgt implementiert.


    class PanesTemplateSelector : DataTemplateSelector {
        public DataTemplate ViewToolTemplate { get; set; }
        public DataTemplate ViewDocTemplate { get; set; }

        public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container) {
            var itemAsLayoutContent = item as LayoutContent;

            if (item is ModelViewerTool) {
                Debug.Print("SelectTemplate: ViewToolTemplate");
                return ViewToolTemplate;
            }

            if (item is ModelViewerDoc) {
                Debug.Print("SelectTemplate: ViewDocTemplate");
                return ViewDocTemplate;
            }

            Debug.Assert(false);
            return base.SelectTemplate(item, container);
        }

        public PanesTemplateSelector() {

        }
    }

    class PanesStyleSelector : StyleSelector {
        public Style ToolStyle { get; set; }
        public Style DocStyle { get; set; }

        public override System.Windows.Style SelectStyle(object item, System.Windows.DependencyObject container) {

            if (item is ModelViewerTool) {
                Debug.Print("SelectStyle: ToolStyle");
                return ToolStyle;
            }

            if (item is ModelViewerDoc) {
                Debug.Print("SelectStyle: DocStyle");
                return DocStyle;
            }

            return base.SelectStyle(item, container);
        }
    }

Wenn das Programm gestartet wird, wird der Instanz von ModelViewerTool kein Template zugeordnet. Es fehlt der hierfür notwendige Aufruf. Im Gegensatz dazu klappt die Zuordnung des Templates für den ModelViewerDoc. Die Zuordnung des Styles funktioniert für alle Beide. Die komplette Liste mit den Debug-Ausgaben aus den Selektoren lauten:SelectStyle: ToolStyle
SelectStyle: DocStyle
SelectStyle: ToolStyle
SelectStyle: DocStyle
SelectTemplate: ViewDocTemplate

Die Panels aus avalondock sind alle sichtbar.

2.207 Beiträge seit 2011
vor 4 Jahren

Hallo schnei01,

willkommen im Forum. Was genau ist deine Frage? Kannst du vielleicht eine Frage in einem Satz aus deinem Beitrag a la "Wie kann ich ..." formulieren?

Gruss

Coffeebean

S
schnei01 Themenstarter:in
2 Beiträge seit 2019
vor 4 Jahren

Hallo Coffeebean,
vielen Dank für deine Antwort. Sorry, dass mein Problem nicht deutlich wurde.

Im Code ist irgendwo ein Fehler, den ich nicht verstehe. Daher das Beipiel.
Ich hatte erwartet, dass mittels des 'PanesTemplateSelector's allen Modell-Instanzen, die der 'DockingManager' über die beiden Listen 'DockingManager.AnchorablesSource' und 'DockingManager.DocumentsSource' aggregiert, ein DataTemplate aus der xaml-Datei zugeordnet wird. Die Grundlage für die Zuordnung bildet die Klassedeklaration und die Implementierung der Selektoren.

Total falsch kann es nicht sein, da die Zuordnung der Style-Eigenschaften für beide Listen mit den obigen Ansatz funktioniert. Für die Zuordnung der Datatemplate-Eigenschaften funktioniet es leider nicht und ich komme einfach nicht auf die Lösung.

Ich würde mich über Ideen, Erfahrungen oder Hinweise freuen, die mir helfen, mein Problem zu lösen. Gibt es irgendwelche Einstellungen in visual studio (2017) die inkompatibel mit den Bibliotheken von avalondock sind. Vielleicht musste schon in dieser Richtung jemand Erfahrung sammeln und kann mir helfen.

Die Xceed-Dokumentation hilft mir nicht weiter und mir sind die Ideen ausgegangen, was ich noch probieren kann.

Gruss schnei01