2013-02-09 3 views
9

여러 항목이있는 ListBox (SelectionMode = Extended 포함)가 있고 상황에 맞는 메뉴 기능을 추가하고 싶습니다. 문제는 일부 조건에 따라 동적으로 컨텍스트 메뉴를 만드는 방법입니다. 예 : 하나의 항목 만 선택되면 일반 컨텍스트 메뉴를 표시하고 하나 이상의 항목이 선택되면 다른 컨텍스트 메뉴 (예 : 새 항목이 추가됨)를 표시하려고합니다. 또한, 세 번째 종류의 컨텍스트 메뉴를 만들려면 선택한 항목 사이에 속성 집합이 하나 이상있는 하나 이상을 만들고 싶습니다. 기타 ... 이와 같은 여러 조건이있을 수 있습니다.WPF : ContextMenu를 동적으로 생성하는 방법

기본적으로 사용자가 마우스 버튼을 마우스 오른쪽 버튼으로 클릭하고 메뉴가 실제로 표시되기 바로 전에 상황에 맞는 메뉴를 동적으로 생성해야합니다. 이것이 가능한가?

답변

6

내 질문에 대한 답변을 찾았으며 ContextMenuOpening 이벤트입니다. 기본적으로이 이벤트를 처리하고 현재 응용 프로그램 상태에 따라 메뉴를 조정해야합니다. 자세한 내용은 여기에서 확인하십시오 : https://msdn.microsoft.com/en-us/library/Bb613568(v=vs.100).aspx

+1

링크가 유효하지 않습니다. – aaron

+0

업데이트 된 문서 : https://msdn.microsoft.com/en-us/library/bb613568.aspx –

+1

문서가 어떤 식 으로든 다시 제거되는 경우 제목은 '처리 방법 : 핸들 ContextMenuOpening Event '를 검색 할 수 있습니다. – Rolfi

3

특정 시나리오에 따라 사용할 미리 정의 된 컨텍스트 메뉴가있는 경우 항상 컨텍스트 메뉴를 리소스로 만들 수 있습니다.

<Window.Resources> 
    <ContextMenu x:Key="Menu1"> 
     <MenuItem>Item1</MenuItem> 
    </ContextMenu> 
    <ContextMenu x:Key="Menu2"> 
     <MenuItem>Item1</MenuItem> 
     <MenuItem>Item2</MenuItem> 
    </ContextMenu> 
</Window.Resources> 

그리고 생성 된 데이터는 ContextMenu 오히려 매우 지저분한 얻을 수 있습니다 나는이에 대한보기 모델이나 뒤에 코드의 속성에 바인딩 제안 아래에 내가 한 일보다, 사용하도록 설정하기 위해 ListBox 트리거 xaml에서. 구현은 여기에서 하나의 항목이 선택되어 있는지 확인하고, 그 경우에 표시되는 컨텍스트 메뉴의 선택은 단지 I 코드에 처리 제안 뷰에 관심있는 경우

<ListBox x:Name="mylist" SelectionMode="Multiple" ContextMenu="{StaticResource Menu2}" > 
    <ListBox.Style> 
     <Style TargetType="{x:Type ListBox}"> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding Path=SelectedItems.Count, RelativeSource={RelativeSource Self}}" Value="1" > 
        <Setter Property="ContextMenu" Value="{StaticResource ResourceKey=Menu1}" /> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </ListBox.Style> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding Path=DisplayName}" /> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

을 메뉴 1로 전환 뒤에. 뷰 모델이 메뉴를 표시 할 몇 가지 관심을 가지고있는 경우

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     // Hook up any events that might influence which menu to show 
     mylist.SelectionChanged += listSelectionChanged; 
     InitializeComponent(); 
    } 

    private void listSelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     var listBox = sender as ListBox; 
     if (listBox == null) 
      return; // Or throw something, hard 

     ContextMenu menuToUse; 
     // Logic for selecting which menu to use goes here 

     listBox.ContextMenu = menuToUse; 
    } 
} 

(그것을 같은 소리하지만 전체 상황을 모르고 얘기하기 어렵다되지 않습니다) 당신이 뷰 모델에서 결정하게 몇 가지 속성을 노출 할 수 있지만 어떤 ContextMenu 표시합니다. 개별 부울 속성보다는 오히려 특정 시점에 부울 중 하나만 true가되는 클래스를 만들려고 할 가능성이 큽니다.

public class MyViewModel : INotifyPropertyChanged 
{ 

    public MyViewModel() 
    { 
     SelectedItems = new ObservableCollection<string>(); 
     SelectedItems.CollectionChanged += SelectedItemsChanged; 
    } 

    private void SelectedItemsChanged(object sender, NotifyCollectionChangedEventArgs e) 
    { 
     // Logic to see which ShowMenuX property to set to true goes here 
    } 

    public ObservableCollection<string> SelectedItems { get; set; } 

    private bool _showMenu1 = false; 
    public bool ShowMenu1 
    { 
     get { return _showMenu1; } 
     set 
     { 
      _showMenu1 = value; 
      RaisePropertyChanged("ShowMenu1"); 
     } 
    } 

    // INotifyPropertyChanged implementation goes here 
} 
+0

매우 도움이되었지만 내 문제를 정확하게 해결하지 못했습니다. 코드 및 상황에 맞는 메뉴를 만들어야합니다. 컨텍스트 메뉴에 영향을 미치는 일부 조건은 코드에서만 확인/계산할 수 있기 때문입니다. – matori82

10

나는 이것이 이전 질문이라는 것을 알고 있습니다. ContextMenu 클래스가 ItemsSource 속성을 통한 바인딩을 지원하기 때문에 MVVM 시나리오에서 OP의 원래 문제를 해결하는 매우 간단한 대답이있는 것 같습니다.

누군가가이 문제를 겪을 때 도움이되기를 바랍니다.

뷰 모델에서 XAML

 <ContextMenu ItemsSource="{Binding Path=ItemList, UpdateSourceTrigger=PropertyChanged}"> 
     </ContextMenu> 

, 동적 현재 응용 프로그램의 상태에 따라 "ITEMLIST"속성을 수정할 수 있습니다.

+6

메뉴 항목에 바인딩 명령을 어떻게 처리합니까? – Julien

+1

@Julien, [this] (http://stackoverflow.com/a/22849063/1997232) 답변을 참조하십시오. – Sinatr

관련 문제