2016-06-16 10 views
2

Nehmen wir an, ich habe eine ListView mit einem ContextMenu. Ich möchte es als separate Steuerung namens ListViewWithContextMenu verwenden. Wie kann ich die Befehlsbindungen von ContextMenu so umleiten, dass sie in ListViewWithContextMenu sichtbar sind?Wie Bindings auf "außerhalb" eines XAML-Steuerelements umgeleitet werden

Beispielcode:

ListViewWithContextMenu.xaml

<ListView x:Class="WpfApplication4.ListViewWithContextMenu" 
     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:local="clr-namespace:WpfApplication4" 
     mc:Ignorable="d" 
     d:DesignHeight="300" d:DesignWidth="300"> 
<ListView.ContextMenu> 
    <ContextMenu> 
     <MenuItem Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:ListViewWithContextMenu}}, Path= PreviewCommand}" /> 
    </ContextMenu> 
</ListView.ContextMenu> 

ListViewWithContextMenu.xaml.cs

using System.Windows; 
using System.Windows.Input; 

namespace WpfApplication4 
{ 
    public partial class ListViewWithContextMenu 
    { 
     public ICommand PreviewCommand 
     { 
      get { return (ICommand)GetValue(PreviewCommandProperty); } 
      set { SetValue(PreviewCommandProperty, value); } 
     } 

     public static readonly DependencyProperty PreviewCommandProperty = 
      DependencyProperty.Register("PreviewCommand", typeof(ICommand), typeof(ListViewWithContextMenu)); 

     public ListViewWithContextMenu() 
     { 
      InitializeComponent(); 
     } 
    } 
} 

MainWindow.xaml

<Window x:Class="WpfApplication4.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:local="clr-namespace:WpfApplication4" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.DataContext><local:MainWidnowViewModel></local:MainWidnowViewModel></Window.DataContext> 
    <Grid> 
      <local:ListViewWithContextMenu PreviewCommand="{Binding Preview}"></local:ListViewWithContextMenu> 
    </Grid> 
</Window> 

MainWindowViewModel.cs

using System.Windows; 
using System.Windows.Input; 
using Microsoft.Practices.Prism.Commands; 

namespace WpfApplication4 
{ 
    public class MainWidnowViewModel 
    { 
     public MainWidnowViewModel() 
     { 
      Preview = new DelegateCommand(PreviewMethod); 
     } 

     private void PreviewMethod() 
     { 
      MessageBox.Show("PREVIEW"); 
     } 

     public ICommand Preview { get; set; } 
    } 
} 

Dieser Code die PreviewMethod in Ansichtsmodell nicht nennen, die ich

+0

Ich habe eine Lösung für Ihr Problem. Geben Sie mir einen Moment, um es als Antwort zu schreiben ... –

Antwort

1

Zunächst einmal achive wollen, statt die Erstellung Ihrer "ListViewWithDataContext" als reguläres Benutzersteuerelement, erstellen Sie es als WPF "CustomControl". Dazu führen Sie die folgenden Schritte aus:

  • löschen Ihre bestehenden „ListViewWithDataContext“ control
  • auf Ihrem Projekt der rechten Maustaste und klicken Sie auf „Neues Element hinzufügen“ -> „Custom Control (WPF)“. Custom Control

  • Visual Studio automatisch einen neuen Projektordner "Themen" und eine neue XAML-Datei erstellen, darunter als "generic.xaml", etwa so:

enter image description here

  • Visual Studio erstellt auch eine direkte C# -Klassendatei mit dem Titel "ListViewWithContextMenu.cs"

Kopieren Sie den folgenden Code und fügen Sie die entsprechenden Dateien von hier aus in:

generic.xaml

<ResourceDictionary 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:local="clr-namespace:WpfApplication4"> 


<Style TargetType="{x:Type local:ListViewWithContextMenu}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type local:ListViewWithContextMenu}"> 
       <Border Background="{TemplateBinding Background}" 
         BorderBrush="{TemplateBinding BorderBrush}" 
         BorderThickness="{TemplateBinding BorderThickness}"> 

        <Border.ContextMenu> 
         <ContextMenu> 
          <MenuItem Command="{TemplateBinding PreviewCommand}" /> 
         </ContextMenu> 
        </Border.ContextMenu> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

ListViewWithContextMenu:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 

namespace WpfApplication4 
{ 

    public class ListViewWithContextMenu : ListView 
    { 

     public ICommand PreviewCommand 
     { 
      get { return (ICommand)GetValue(PreviewCommandProperty); } 
      set { SetValue(PreviewCommandProperty, value); } 
     } 

     public static readonly DependencyProperty PreviewCommandProperty = 
     DependencyProperty.Register("PreviewCommand", typeof(ICommand), typeof(ListViewWithContextMenu)); 


     static ListViewWithContextMenu() 
     { 
      DefaultStyleKeyProperty.OverrideMetadata(typeof(ListViewWithContextMenu), new FrameworkPropertyMetadata(typeof(ListViewWithContextMenu))); 
     } 
    } 
} 

ich es getestet, und es funktioniert.

It works

Was wir haben hier: Da alles, was wir tun möchten, ist die bestehende Listview-Steuerelement zu nutzen, aber keine der bestehenden UI Erscheinungen ändern, werden wir einfach ein Listview „Custom“ geschaffen, die im Wesentlichen Überschreibt die aktuelle Vorlage. In der CS-Datei haben wir PreviewCommand DependencyProperty definiert.

In der Generic.xaml-Datei haben wir einen "Border" als Steuerelement auf root-level verwendet, um das Control aufzunehmen (obwohl wir ein Grid oder whatnot hätten verwenden können), und wir haben ein Kontextmenü hinzugefügt.

+1

Vielen Dank für Ihre Antwort! Ich werde es morgen testen :) – SebOlens

+0

Kein Problem! Treffe mich, wenn du Fragen zu meiner Antwort hast. –

Verwandte Themen