2014-09-18 2 views
0

Node 클래스 :의 ContextMenu 바운드 개체의 열거에 따라

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.Linq; 
using System.Text; 

namespace FrontEnd 
{ 
    public enum NodeType 
    { 
     SQLite, 
     Database, 
     TableCollection, 
     ViewCollection, 
     IndexCollection, 
     TriggerCollection, 
     ColumnCollection, 
     Table, 
     View, 
     Column, 
     Index, 
     Trigger 
    } 

    public class Node 
    { 
     public string Title { get; protected set; } 
     public NodeType Type { get; protected set; } 
     public ObservableCollection<Node> Nodes { get; set; } 

     public Node(string title, NodeType type) 
     { 
      this.Title = title; 
      this.Type = type; 
      this.Nodes = new ObservableCollection<Node>(); 
     } 
    } 
} 

내 XAML이 :

내가 달성하기 위해 노력하고 있고 실패는 ContextMenu을 결정하는 것입니다 무엇
<TreeView Name="dbTree" Padding="0,5,0,0"> 
     <TreeView.Resources> 
      <ContextMenu x:Key="ScaleCollectionPopup"> 
       <MenuItem Header="New Scale..."/> 
      </ContextMenu> 
      <ContextMenu x:Key="ScaleItemPopup"> 
       <MenuItem Header="Remove Scale"/> 
      </ContextMenu> 
     </TreeView.Resources> 
     <TreeView.ItemContainerStyle> 
      <Style TargetType="TreeViewItem"> 
       <Style.Triggers> 
        <DataTrigger Binding="{Binding Type, RelativeSource={RelativeSource Self}}" Value="NodeType.Column"> 
         <Setter Property="ContextMenu" Value="{StaticResource ScaleItemPopup}" /> 
        </DataTrigger> 
       </Style.Triggers> 
      </Style> 
     </TreeView.ItemContainerStyle> 
     <TreeView.ItemTemplate> 
      <HierarchicalDataTemplate ItemsSource="{Binding Nodes}"> 
       <StackPanel Orientation="Horizontal" Margin="0,0,0,4"> 
        <Image Source="{Binding Converter={StaticResource StringToImageConverter}}" /> 
        <TextBlock Text="{Binding Title}" Padding="5,0,0,0" /> 
       </StackPanel> 
      </HierarchicalDataTemplate> 
     </TreeView.ItemTemplate> 
    </TreeView> 

에 기초 사용하기 Type 바운드 속성은 Node 클래스입니다.

테이블 또는 뷰 "1000 행 선택"& "SHOW CREATE SQL"을 표시하려면 다른 유형에 대해 다른 옵션을 정의하고 싶습니다.

원하는 효과를 얻으려면 올바른 방법은 무엇입니까?

+0

데이터 템플릿 및 데이터 트리거를 사용하면 원하는대로 메뉴를 전환 할 수 있습니다. – pushpraj

+0

@pushpraj 위와 같은 방법으로 볼 수는 있지만 작동하지 않습니다. 누군가 내 실수를 밝힐 수 있기를 바랍니다. – sprocket12

+0

Treeview의 ItemsSource 란 무엇입니까? 또한''을 시도하십시오. 출력 창에 표시되는 데이터 바인딩 오류를 확인하십시오. 필요한 경우 스타일 리소스로 리소스를 이동하려고 할 수도 있습니다. – pushpraj

답변

1

각 노드의보기 모델에서 컨텍스트 메뉴를 생성 할 때 mvvm 스타일로 선호합니다.

보기 부분 : 아래의 예를 참조

<Window x:Class="WpfApplication1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:wpfApplication1="clr-namespace:WpfApplication1" 
    mc:Ignorable="d" 
    Title="MainWindow" Height="350" Width="525" 
    d:DataContext="{d:DesignInstance wpfApplication1:ViewModel}"> 
<Grid> 
    <TreeView ItemsSource="{Binding Path=Nodes}"> 
     <TreeView.ItemTemplate> 
      <HierarchicalDataTemplate ItemsSource="{Binding Nodes}"> 
       <StackPanel> 
        <StackPanel.ContextMenu> 
         <ContextMenu ItemsSource="{Binding ContextMenu}"> 
          <ContextMenu.Resources> 
           <Style TargetType="MenuItem"> 
            <Setter Property="Command" Value="{Binding Command}"/> 
           </Style> 
          </ContextMenu.Resources> 
          <ContextMenu.ItemTemplate> 
           <HierarchicalDataTemplate ItemsSource="{Binding Items}"> 
            <TextBlock Text="{Binding Title}"/> 
           </HierarchicalDataTemplate> 
          </ContextMenu.ItemTemplate> 
         </ContextMenu> 
        </StackPanel.ContextMenu> 
        <TextBlock Text="{Binding Title}"/> 
       </StackPanel> 
      </HierarchicalDataTemplate> 
     </TreeView.ItemTemplate> 
    </TreeView> 
</Grid> 

그리고보기 모델 부분 :

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     DataContext = new ViewModel(); 
    } 
} 

public class MenuItem 
{ 
    public MenuItem() 
    { 
     Items = new ObservableCollection<MenuItem>(); 
    } 

    public string Title { get; set; } 
    public ICommand Command { get; set; } 
    public ObservableCollection<MenuItem> Items { get; private set; } 
} 

public class ViewModel 
{ 
    public ViewModel() 
    { 
     Nodes = new ObservableCollection<Node> 
     { 
      new Node("MSSQL", NodeType.Database, 
       new Node("Customers", NodeType.Table)), 
      new Node("Oracle", NodeType.Database) 
     }; 
    } 

    public ObservableCollection<Node> Nodes { get; set; } 
} 

public enum NodeType 
{ 
    Database, 
    Table, 
} 

public class Node 
{ 
    public string Title { get; protected set; } 
    public NodeType Type { get; protected set; } 
    public ObservableCollection<Node> Nodes { get; set; } 

    public Node(string title, NodeType type, params Node[] nodes) 
    { 
     this.Title = title; 
     this.Type = type; 
     this.Nodes = new ObservableCollection<Node>(); 
     if (nodes != null) 
      nodes.ToList().ForEach(this.Nodes.Add); 
    } 

    public IEnumerable<MenuItem> ContextMenu 
    { 
     get { return createMenu(this); } 
    } 

    private static IEnumerable<MenuItem> createMenu(Node node) 
    { 
     switch (node.Type) 
     { 
      case NodeType.Database: 
       return new List<MenuItem> 
       { 
        new MenuItem {Title = "Create table...", Command = new RelayCommand(o => MessageBox.Show("Table created"))} 
       }; 
      case NodeType.Table: 
       return new List<MenuItem> 
       { 
        new MenuItem {Title = "Select..."}, 
        new MenuItem {Title = "Edit..."} 
       }; 
      default: 
       return null; 
     } 
    } 
} 

public class RelayCommand : ICommand 
{ 
    #region Fields 

    readonly Action<object> _execute; 
    readonly Predicate<object> _canExecute; 

    #endregion // Fields 

    #region Constructors 

    public RelayCommand(Action<object> execute) 
     : this(execute, null) 
    { 
    } 

    public RelayCommand(Action<object> execute, Predicate<object> canExecute) 
    { 
     if (execute == null) 
      throw new ArgumentNullException("execute"); 

     _execute = execute; 
     _canExecute = canExecute; 
    } 
    #endregion // Constructors 

    #region ICommand Members 

    [DebuggerStepThrough] 
    public bool CanExecute(object parameter) 
    { 
     return _canExecute == null || _canExecute(parameter); 
    } 

    public event EventHandler CanExecuteChanged 
    { 
     add { CommandManager.RequerySuggested += value; } 
     remove { CommandManager.RequerySuggested -= value; } 
    } 

    public void Execute(object parameter) 
    { 
     _execute(parameter); 
    } 

    #endregion // ICommand Members 
} 

(당신이 어떤 구현 ICommand의 인터페이스를 사용할 수 있습니다, RelayCommand가 그 중 하나입니다) 노드 생성자에 전달할 수있는 Node 클래스 또는 IContextMenuBuilder 서비스에서 메뉴 항목을 생성 할 수 있습니다.

+0

좋은 예를 들어, 행복하게 코딩 :) – pushpraj