Domanda

Che cosa sto facendo male qui:?

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

Questo è solo un esempio semplificato, che non funziona in ogni caso :) In realtà ho bisogno di ottenere un valore da un'altra proprietà che è in ambito di DataContext della finestra.

Help me pls.

È stato utile?

Soluzione

Questo è difficile perché descrizione comandi non è parte del VisualTree. Qui si vede una soluzione di fresco per lo stesso problema con contextmenus. Allo stesso modo si può andare per la descrizione comandi.

Aggiorna
Purtroppo il collegamento è andato e non ho trovato più l'articolo citato.
Per quanto mi ricordo, il blog di riferimento ha mostrato come si legano a un DataContext di un altro VisualTree, che è spesso necessay quando vincolante da una descrizione comandi, un ContextMenu o di un'altra.

Un bel modo per fare questo, è quello di fornire l'istanza desiderata (ad esempio ViewModel) all'interno del Tag-proprietà del PlacementTarget. L'esempio seguente fa questo per l'accesso a un comando di istanza di un ViewModel:

<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>

non ho provato e il suo tempo ho fatto l'ultima volta. Si prega di fare un commento, se non funziona per voi.

UPDATE 2

Mentre il link originale che questa risposta è stato tradotto è andato, mi ha colpito archive.org e trovato la voce blog originale . Eccolo, pari pari dal blog:

  

Perché un ContextMenu in WPF non esiste all'interno della struttura visiva di   la tua pagina / finestra / controllo di per sé, l'associazione di dati può essere un po 'difficile.   Ho cercato di alta e bassa in tutto il web per questo, e il più   risposta comune sembra essere “just do it nel codice dietro”. SBAGLIATO! io   non è venuto per il meraviglioso mondo di XAML di essere tornare a   fare le cose nel codice dietro.

     

Ecco il mio esempio per che vi permetterà di legarsi a una stringa che   esiste come una proprietà della finestra.

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>
     

La parte importante è il tag sul pulsante (anche se si potrebbe altrettanto   facilmente impostare il DataContext del pulsante). Questo contiene un riferimento a   la finestra padre. ContextMenu è in grado di accedere a questo   attraverso di essa della struttura PlacementTarget. È quindi possibile passare questo contesto   verso il basso attraverso voci di menu.

     

Lo ammetto questa non è la soluzione più elegante del mondo.   Tuttavia, batte roba impostazione nel codice dietro. Se qualcuno ha un   ancora migliore modo per fare questo mi piacerebbe sentire.

Altri suggerimenti

Per di seguito:
PlacementTarget è il controllo che possiede il ContextMenu (es: DataGrid). Non c'è bisogno di una proprietà "tag".

IsEnabled si lega al valore "myProperty" del DataGrid.

Ho provato questo e funziona. Stava avendo problema simile con il legame.

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

A causa ContextMenu non è nella struttura visiva, vincolante non funzionerà. una soluzione semplice utilizza pattern Proxy, è possibile creare una classe wrapper che eredita da DependencyObject e ha un DependencyProperty che manterrà un DataContext del vostro Window, allora si può avere una risorsa della delega in XAML e, infine, si legano vostro comando MenuItem al tuo comando desiderato tramite l'oggetto proxy.
Esempio 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));

}

Come utilizzare in XAML:

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

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

Che cosa sta succedendo?
Proprietà Data di ProxyClass si legherà DataContext di Window, allora ha tutte le vostre comamnds e proprietà del ViewModel all'interno della risorsa ProxyClass.
un altro vantaggio di questo approccio è la portabilità e riutilizzare in più viste e progetti.

Credo che dovrebbe essere fatto in questo modo:

{Binding Path=Title, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top