2016-04-20 64 views
1

私はCustomControlとそのコントロールのビューモデルのリストを持っています。 ItemsControlを使用して、各ビューモデルのコントロールを動的に作成することができます。今私はAvalonDockを使用して、生成されたUserControlごとに1つのDockableContentを追加したいとします。どのようにこれを動的に行うことができますか?DockablePanesを動的に追加します

答えて

2

あなたがドッキングマネージャのDocumentSourceにのviewmodelsのあなたのコレクションをバインドすると、このようななどのタイトルなどのプロパティにバインドするためにテンプレートを設定します。

<dock:DockingManager DocumentsSource="{Binding Documents}" > 
    <dock:DockingManager.LayoutItemContainerStyle> 
     <Style TargetType="{x:Type dockctrl:LayoutItem}"> 
      <Setter Property="Title" Value="{Binding Model.Title}" /> 
      <Setter Property="CloseCommand" Value="{Binding Model.CloseCommand}" /> 
      <Setter Property="CanClose" Value="{Binding Model.CanClose}" /> 
     </Style> 
    </dock:DockingManager.LayoutItemContainerStyle> 
</dock:DockingManager> 

を、動的にこのようなものを使用して、物事を追加:

Documents.Add(MyNewlyCreatedViewModel) 

編集:あなたは、静的なペインを使用する場合物事をより複雑に。テンプレートセレクタを使用して、通常/固定枠に適したテンプレートを選択する必要があります。 MVVM AvalonDockのサンプルはかなり良いです。ここで私はそれを実現してきた方法です(ツールは静的です):

public class LayoutUpdateStrategy : ILayoutUpdateStrategy 
{ 
    public void AfterInsertAnchorable(LayoutRoot layout, LayoutAnchorable anchorableShown) 
    {} 

    public void AfterInsertDocument(LayoutRoot layout, LayoutDocument anchorableShown) 
    {} 

    public bool BeforeInsertAnchorable(LayoutRoot layout, LayoutAnchorable anchorableToShow, ILayoutContainer destinationContainer) 
    { 
     //AD wants to add the anchorable into destinationContainer 
     //just for test provide a new anchorablepane 
     //if the pane is floating let the manager go ahead 
     LayoutAnchorablePane destPane = destinationContainer as LayoutAnchorablePane; 
     if (destinationContainer != null && 
      destinationContainer.FindParent<LayoutFloatingWindow>() != null) 
      return false; 

     var toolsPane = layout.Descendents().OfType<LayoutAnchorablePane>().FirstOrDefault(d => d.Name == "ToolsPane"); 
     if (toolsPane != null) 
     { 
      toolsPane.Children.Add(anchorableToShow); 
      return true; 
     } 
     return false; 
    } 

    public bool BeforeInsertDocument(LayoutRoot layout, LayoutDocument anchorableToShow, ILayoutContainer destinationContainer) 
    { 
     return false; 
    } 
} 

カスタムレイアウトセレクター:カスタムクラスLayoutUpdateStrategyと

<avalonDock:DockingManager 
     AnchorablesSource="{Binding Tools}" 
     DocumentsSource="{Binding Documents}" 
     AllowMixedOrientation="True" > 
     <avalonDock:DockingManager.Theme> 
      <avalonDock:MetroTheme /> 
     </avalonDock:DockingManager.Theme> 
     <avalonDock:DockingManager.LayoutUpdateStrategy> 
      <helpers:LayoutUpdateStrategy /> 
     </avalonDock:DockingManager.LayoutUpdateStrategy> 
     <avalonDock:DockingManager.LayoutItemContainerStyleSelector> 
      <helpers:AutobinderLayoutSelector> 
       <helpers:AutobinderLayoutSelector.DocumentStyle> 
        <Style TargetType="{x:Type avalonDock:LayoutItem}"> 
         <Setter Property="Title" Value="{Binding Model.Title}" /> 
        </Style> 
       </helpers:AutobinderLayoutSelector.DocumentStyle> 
       <helpers:AutobinderLayoutSelector.ToolStyle> 
        <Style TargetType="{x:Type avalonDock:LayoutItem}"> 
         <Setter Property="Title" Value="{Binding Model.Title}" /> 
         <Setter Property="IconSource" Value="{Binding Model.IconSource}"/> 
        </Style> 
       </helpers:AutobinderLayoutSelector.ToolStyle> 
      </helpers:AutobinderLayoutSelector> 
     </avalonDock:DockingManager.LayoutItemContainerStyleSelector> 
     <avalonDock:DockingManager.LayoutItemTemplateSelector> 
      <helpers:AutobinderTemplateSelector> 
       <helpers:AutobinderTemplateSelector.DocumentTemplate> 
        <DataTemplate> 
         <ContentControl cal:View.Model="{Binding . }" IsTabStop="False" /> 
        </DataTemplate> 
       </helpers:AutobinderTemplateSelector.DocumentTemplate> 
       <helpers:AutobinderTemplateSelector.ToolTemplate> 
        <DataTemplate> 
         <ContentControl cal:View.Model="{Binding . }" IsTabStop="False" /> 
        </DataTemplate> 
       </helpers:AutobinderTemplateSelector.ToolTemplate> 
      </helpers:AutobinderTemplateSelector> 
     </avalonDock:DockingManager.LayoutItemTemplateSelector> 

     <avalonDock:LayoutRoot> 
      <avalonDock:LayoutPanel Orientation="Horizontal"> 
       <avalonDock:LayoutDocumentPane/> 
       <avalonDock:LayoutAnchorablePane Name="ToolsPane" DockWidth="240"/> 
      </avalonDock:LayoutPanel> 
     </avalonDock:LayoutRoot> 
    </avalonDock:DockingManager> 

class AutobinderLayoutSelector : StyleSelector 
{ 
    public Style DocumentStyle { get; set; } 
    public Style ToolStyle { get; set; } 

    public override Style SelectStyle(object item, DependencyObject container) 
    { 
     //check if the item is an instance of TestViewModel 
     if (item is IDockToolBar) 
      return DocumentStyle; 
     else if (item is IDockDocument) 
      return ToolStyle; 

     //delegate the call to base class 
     return base.SelectStyle(item, container); 
    } 
} 

とカスタムTemplateSelector:

public class AutobinderTemplateSelector : DataTemplateSelector 
{ 
    public DataTemplate DocumentTemplate { get; set; } 
    public DataTemplate ToolTemplate { get; set; } 

    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     //check if the item is an instance of TestViewModel 
     if (item is IDockToolBar) 
      return DocumentTemplate; 
     else if (item is IDockDocument) 
      return ToolTemplate; 

     //delegate the call to base class 
     return base.SelectTemplate(item, container); 
    } 
} 

public class AutobinderTemplate : DataTemplate 
{ 

} 

public interface IDockToolBar { 
    bool IsVisible { get; set; } 
} 

public interface IDockDocument { } 
+0

ありがとうございます。私は明日これを試してみる。 DocumentManagerに1つまたはMordの静的なDocumentPanesが含まれている場合でも動作しますか?または、静的にDocumentManagerを、動的にDocumentManagerを使用する必要がありますか? – ooorndtski

+0

スタティックペインを追加すると、はるかに複雑になります。私の編集を参照してください - レイアウトとテンプレートセレクタを使用する必要があります。 – Joe

+0

バージョン2.0未満のAvalonDockを使用する場合でも可能ですか?私は現在1.3を使用しています。 – ooorndtski

関連する問題