Родословные привязки от подсказки или контекстно

StackOverflow https://stackoverflow.com/questions/3668654

Вопрос

Что я здесь не так?

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

Это просто упрощенный пример, который все равно не работает :) На самом деле мне нужно получить значение из другого свойства, которое находится в объеме DataContext окна.

Помоги мне пожалуйста.

Это было полезно?

Решение

Это сложно, потому что всплывающая подсказка не является частью VisualTree. Здесь Вы видите прохладное решение для той же проблемы с контекстуменными. Так же, как вы можете пойти на подсказку.

ОБНОВИТЬ
К сожалению, ссылка ушла, и я больше не нашел ссылочную статью.
Насколько я помню, ссылочный блог показал, как связываться с DataContext другого Visualtree, который часто является обязательным при привязке от подсказки, контекстмена или всплывающим окном.

Хороший способ сделать это, состоит в том, чтобы обеспечить желаемый экземпляр (например, ViewModel) в свойство Tag-свойство размещения PlactementTarget. В следующем примере это делает это для доступа к командным экземпляре 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>

Я не проверил это и долгое время я сделал это в последний раз. Пожалуйста, сделайте комментарий, если это не работает для вас.

Обновление 2.

Как оригинальная ссылка, что этот ответ был написан о, ушел, я попал в Archive.org и нашел оригинальную запись в блоге. Отказ Вот это, дословно из блога:

Потому что контекстумен в WPF не существует в визуальном дереве вашей страницы / окна / управления как SE, привязка данных может быть немного сложно. Я искал высоко и низко через Интернет для этого, и наиболее распространенный ответ, кажется, «просто делай это в коде позади». НЕПРАВИЛЬНО! Я не пришел в замечательный мир XAML, чтобы вернуться к тому, чтобы делать вещи в коде.

Вот мой пример, чтобы позволить вам привязать к строке, которая существует как свойство вашего окна.

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>

Важная часть - это тег на кнопке (хотя вы можете так же легко установить DataContext кнопки). Это хранит ссылку на родительское окно. ContextMenu способен доступ к этому через свой свойство размещения размещения. Затем вы можете пройти этот контекст вниз по пунктам меню.

Я признаю, что это не самое элегантное решение в мире. Тем не менее, он бьет настройки в коде позади. Если у кого-то есть еще лучший способ сделать это, я хотел бы услышать это.

Другие советы

За ниже:
PlactementTarget - это элемент управления, который принадлежит контекстному (например, DataGrid). Нет необходимости в собственности «тега».

IseNiabled Персонально со значением «MyProperty» DataGrid «MyProperty».

Я проверил это, и это работает. Имел подобную проблему с обязательным.

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

Потому что ContextMenu не в визуальном дереве, связывание не будет работать. Простое решение использует рисунок прокси, вы можете создать класс обертки, который наследует от DependencyObject и имеет А. DependencyProperty это будет держать DataContext вашей Window, тогда вы можете иметь ресурс прокси в XAML и, наконец, связываете ваш MenuItem Команда на желаемую команду через прокси-объект.
Образец прокси:

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

}

Как использовать в 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>

Что происходит?
Data свойство ProxyClass Будет связывать DataContext из Window, Тогда у него все ваши коммунты и свойства вашего ViewModel внутри ProxyClass ресурс.
Еще одним преимуществом этого подхода является переносимость и повторно использование в нескольких видах и проектах.

Я думаю, что это должно быть сделано так:

{Binding Path=Title, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top