Frage

Was mache ich falsch hier:

 <GridViewColumn>
    <GridViewColumn.CellTemplate>
       <DataTemplate>
          <Button>
            <Button.ToolTip>
              <TextBlock Text="{Binding Path=Title, RelativeSource={RelativeSource AncestorType=Window}}" />

Das ist nur ein vereinfachtes Beispiel, das ohnehin nicht funktioniert :) Eigentlich muß ich von einer anderen Eigenschaft einen Wert erhalten, die in Rahmen des Fensters Datacontext ist.

Help me pls.

War es hilfreich?

Lösung

Das ist schwierig, weil Quick-Info nicht Teil der VisualTree ist. Hier eine kühle Lösung sehen für das gleiche Problem mit Kontextmenüs. Auf die gleiche Weise können Sie für die Quick-Info gehen.

UPDATE
Leider ist die Verbindung weg und ich habe nicht den angegebenen Artikel gefunden mehr.
Soweit ich mich erinnere, hat das referenzierte Blog, wie man eine Datacontext eines anderen VisualTree zu binden gezeigt, die oft necessay ist, wenn sie von einer Quick-Info, ein ContextMenu oder einem Popup-Bindung.

Ein schöner Weg, dies zu tun, ist die gewünschte Instanz zur Verfügung zu stellen (z Ansichtsmodelles) innerhalb der Tag-Eigenschaft des Placement. Das folgende Beispiel macht dies eine Befehl Instanz eines Ansichtsmodell für den Zugriff auf:

<Button Tag="{Binding DataContext,RelativeSource={RelativeSource Mode=Self}}">
  <Button.ContextMenu>
    <ContextMenu>
       <MenuItem Command="{Binding PlacementTarget.Tag.DesiredCommand,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ContextMenu}}" .../>
    <ContextMenu>
  </Button.ContextMenu>
</Button>

Ich habe es nicht getestet und seine lange, ich habe dies das letzte Mal. Bitte stellen Sie einen Kommentar, wenn es nicht für Sie arbeiten.

UPDATE 2

Als Original-Link, dass diese Antwort geschrieben wurde über gegangen ist, ich traf archive.org und den ursprünglichen Blog-Eintrag . Hier ist sie, wörtlich aus dem Blog:

Da ein ContextMenu in WPF existiert nicht innerhalb der visuellen Struktur der Ihre Seite / Fenster / Steuerung per se, Bindungsdaten ein wenig schwierig sein kann. Ich habe hohe und niedrige über die Bahn für diese gesucht, und die meisten gemeinsame Antwort scheint „tun Sie es einfach in dem Code hinter“ zu sein. FALSCH! ich nicht in der wunderbaren Welt von XAML kam in seine zurück zu Dinge zu tun, in dem Code-behind.

Hier ist mein Beispiel, dass Sie binden an einer Schnur ermöglicht, dass existiert als eine Eigenschaft des Fensters.

public partial class Window1 : Window
{
    public Window1()
    {
        MyString = "Here is my string";
    }

    public string MyString
    {
        get;
        set;

    }
}


<Button Content="Test Button" 
     Tag="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}}">
  <Button.ContextMenu>
    <ContextMenu DataContext="{Binding Path=PlacementTarget.Tag, 
          RelativeSource={RelativeSource Self}}" >
      <MenuItem Header="{Binding MyString}"/>
    </ContextMenu>
  </Button.ContextMenu>   
</Button>

Der wichtige Teil ist der Tag auf der Schaltfläche (obwohl man könnte genauso leicht die Datacontext der Taste eingestellt ist). Dies speichert eine Referenz auf das übergeordnete Fenster. Die ContextMenu ist in der Lage den Zugriff auf diese durch die es Placement Eigenschaft. Anschließend können Sie diesen Kontext übergeben nach unten durch Ihre Menüpunkte.

Ich gebe dies in der Welt nicht die eleganteste Lösung ist. Doch es schlägt Einstellung Sachen in dem Code-behind. Wenn jemand ein noch besserer Weg, dies zu tun, würde ich gerne hören.

Andere Tipps

Per unten:
Placement ist die Steuerung, die die ContextMenu besitzt (zB: Datagrid). Keine Notwendigkeit für eine „tag“ Eigenschaft.

IsEnabled bindet sich an die „myProperty“ Wert des Datagrid.

Getestet habe ich diese und es funktioniert. Wurde mit ähnlichem Problem mit der Bindung.

<ContextMenu
DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Self}}"
IsEnabled="{Binding myProperty}"  
>

Da ContextMenu nicht in visueller Struktur ist, wird die Bindung nicht. eine einfache Lösung wird unter Verwendung von Proxy-Muster, können Sie eine Wrapper-Klasse erstellen, die erbt von DependencyObject und hat eine DependencyProperty, die eine DataContext Ihrer Window halten, dann können Sie eine Ressource des Proxy in XAML haben und schließlich binden Ihre MenuItem Befehl an Ihre Befehl über das Proxy-Objekt gewünscht wird.
Beispiel Proxy:

Public class ProxyClass : DependencyObject
{
    Public object Data {get; set;}
   public static readonly DependencyProperty DataProperty = DependencyProperty.Register("DataProperty", typeof(object), typeof(ProxyClass), new FrameworkPropertyMetadata(null));

}

Wie in XAML verwenden:

<Window DataContext="{Binding MyViewModel}">
...
<Window.Resources>
    <ProxyClass Data={Binding} x:Key="BindingProxy"/>

</Window.Resources>
...  
<MenuItem Command="{Binding Source={StaticResource BindingProxy}, Path=Data.MyDesiredCommand"/>
...
</Window>

Was ist passiert?
Data Eigentum von ProxyClass zu DataContext von Window binden wird, dann hat es alle Ihre comamnds und Eigenschaften Ihres ViewModel innerhalb der ProxyClass Ressource.
Ein weiterer Vorteil dieses Ansatzes ist die Portabilität und Wiederverwenden in mehreren Ansichten und Projekten.

ich denke, es sollte wie folgt geschehen:

{Binding Path=Title, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top