2017-01-25 6 views
0

Я создал Контекстный стиль меню с предопределенной MenuItems в нем:Присвоить обработчик событий ContextMenu элемента определяется в пользовательском стиле

<Style TargetType="{x:Type ContextMenu}" x:Key="DataGridColumnFilterContextMenu">     
       <Setter Property="ContextMenu.Template"> 
       <Setter.Value> 
        <ControlTemplate> 
         <Border BorderBrush="#868686" 
           BorderThickness="1" 
           Background="#FAFAFA"> 
           <Grid MaxHeight="500"> 
           <Grid.RowDefinitions> 
            <RowDefinition Height="Auto"/> 
            <RowDefinition Height="*"/> 
           </Grid.RowDefinitions> 
           <StackPanel> 
            <MenuItem Header="Filtrēt" StaysOpenOnClick="True" Name="DynSearch"> 
             <MenuItem.Icon> 
              <Image RenderOptions.BitmapScalingMode="NearestNeighbor" 
                RenderOptions.EdgeMode="Aliased" 
                Source="/Furniture;component/Resources/search4.png" /> 
             </MenuItem.Icon> 
            </MenuItem> 
            <Separator Margin="20 5 20 0" Height="2" Width="Auto" /> 
            <MenuItem Margin="5 5 0 0" StaysOpenOnClick="True" > 
             <MenuItem.Template> 
              <ControlTemplate > 
               <CheckBox Padding="15 0 0 0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >Iezīmēt/Atzīmēt visus</CheckBox> 
              </ControlTemplate> 
             </MenuItem.Template> 
             <MenuItem.Icon> 
              <Image RenderOptions.BitmapScalingMode="NearestNeighbor" 
                RenderOptions.EdgeMode="Aliased" 
                Source="/Furniture;component/Resources/search4.png" /> 
             </MenuItem.Icon> 
            </MenuItem> 
            <Separator Margin="20 5 20 0" Height="2" Width="Auto" /> 
            <RadioButton Margin="5 5 0 0" Padding="15 0 0 0" GroupName="Sorting" Content="Augoša secībā" IsChecked="True"/> 
            <RadioButton Margin="5 5 0 0" Padding="15 0 0 0" GroupName="Sorting" Content="Dilstoša secībā" /> 
            <Separator Margin="20 5 20 5" Height="2" Width="Auto" /> 
           </StackPanel> 
           <ScrollViewer Grid.Row="1" 
               Margin="1,0,1,0"            
               CanContentScroll="True" 
               VerticalScrollBarVisibility="Auto" 
               Grid.ColumnSpan="2"> 
             <ItemsPresenter KeyboardNavigation.DirectionalNavigation="Cycle" /> 
            </ScrollViewer> 
           </Grid>        
         </Border> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 

Теперь я назначил стиль нового ContextMenu и хотел назначить Нажмите обработчик события для MenuItem определен в стиль с заголовком «Filtrēt». Я попытался сделать это как следующее:

ContextMenu cm = new ContextMenu(); 
cm.Style = Application.Current.Resources["DataGridColumnFilterContextMenu"] as Style; 
var controlList = ((((cm.Template.LoadContent() as Border).Child as Grid).Children)[0] as StackPanel).Children; 
MenuItem filterItem = (controlList[0] as MenuItem); 
filterItem.Click += MiFiltre_Click; 

И когда я нажал отладчик Он не пришел к методу MiFiltre_Click. Я пробовал разные события, такие как MouseDown и PreviewMouseDown. Также я попытался связать ICommand, и это тоже не сработало.

Затем я искал этот вопрос и понял, что cm.Template.LoadContent() может фактически создать новый экземпляр моего шаблона ContextMenu, и я пытаюсь связать обработчик событий с другим экземпляром элемента управления. Затем я попытался получить элементы управления узлом ContextMenu с помощью VisualTreeHelper и LogicalTreeHelper, и это также не сработало.

Так вот вопросы:

  1. Как достичь Нажмите привязки обработчика событий?
  2. Если 1-ый вопрос слишком трудно, то как получить текущий экземпляр ContextMenu child, определенный в обычном стиле?

ответ

0

Я собираюсь предположить это меню. Стиль определен в ресурсном словаре под названием «MyResources.xaml».

  1. Создайте файл класса в той же папке проекта и назовите его «MyResources.xaml.cs».

  2. Сделать это частичный класс, как это:

    namespace WhateverNamespace 
    { 
        public partial class MyResources 
        { 
         private void FilterMenuItem_Click(object sender, RoutedEventArgs e) 
         { 
          MenuItem mi = (MenuItem)sender; 
    
          // Below, PlacementTarget is the control the user right-clicked on. 
          // Use that directly if you want that instead of its viewmodel. 
    
          // This works with the conventional ContextMenu defined below. 
          //ViewModel viewModel = ((FrameworkElement)((ContextMenu)mi.Parent).PlacementTarget).DataContext as ViewModel; 
    
          // This works with your template design. The only difference is 
          // TemplatedParent instead of Parent. 
          ViewModel viewModel = 
           ((FrameworkElement)((ContextMenu)mi.TemplatedParent).PlacementTarget) 
           .DataContext as ViewModel; 
    
          MessageBox.Show("FilterMenuItem_Click"); 
         } 
        } 
    } 
    
  3. Дайте словарь ресурсов в x:Class атрибут:

    <ResourceDictionary 
        x:Class="WhateverNamespace.MyResources" 
    
  4. Wire до обработчика:

    <MenuItem 
        Click="FilterMenuItem_Click" 
        Header="Filtrēt" 
        StaysOpenOnClick="True" 
        Name="DynSearch"> 
    

Кстати, вам не нужно возиться с стилями и шаблоны для создания ContextMenu ресурса:

<ContextMenu x:Key="DataGridColumnFilterContextMenu"> 
    <MenuItem 
     Click="FilterMenuItem_Click" 
     Header="Filtrēt" 
     StaysOpenOnClick="True" 
     Name="DynSearch"> 
     <MenuItem.Icon> 
      <Image 
       RenderOptions.BitmapScalingMode="NearestNeighbor" 
       RenderOptions.EdgeMode="Aliased" 
       Source="/Furniture;component/Resources/search4.png" 
       /> 
     </MenuItem.Icon> 
    </MenuItem> 
    <Separator /> 
    <MenuItem StaysOpenOnClick="True"> 
     <MenuItem.Header> 
      <CheckBox>Iezīmēt/Atzīmēt visus</CheckBox> 
     </MenuItem.Header> 
     <MenuItem.Icon> 
      <Image 
       RenderOptions.BitmapScalingMode="NearestNeighbor" 
       RenderOptions.EdgeMode="Aliased" 
       Source="/Furniture;component/Resources/search4.png" 
       /> 
     </MenuItem.Icon> 
    </MenuItem> 
    <Separator /> 
    <MenuItem> 
     <MenuItem.Header> 
      <RadioButton GroupName="Sorting" Content="Augoša secībā" IsChecked="True"/> 
     </MenuItem.Header> 
    </MenuItem> 
    <MenuItem> 
     <MenuItem.Header> 
      <RadioButton GroupName="Sorting" Content="Dilstoša secībā" IsChecked="True"/> 
     </MenuItem.Header> 
    </MenuItem> 
</ContextMenu> 
+0

Я не могу сделать это, потому что мне нужно использовать некоторые переменные в обработчике события из другого экземпляра класса. Кстати, я сохраняю этот стиль в App.xaml. –

+0

@Andrew_Miller См. Обновление для одного способа доступа к viewmodel в обработчике Click. Я никогда не видел, чтобы контекстное меню было реализовано так, как вы есть, но я уверен, что вы могли бы найти способ. –

+0

@Andrew_Miller Упс, это оказалось довольно легко. Обновление снова. –

Смежные вопросы