WPF Binding: где свойство содержит путь к значению - PullRequest
4 голосов
/ 10 июня 2009

У меня есть расширитель с парой TextBlocks в верхней панели, который я использую, чтобы дать название и часть ключевой информации.

В идеале я хочу указать путь к ключевой части информации, но я не могу понять, как связать путь привязки с другим путем (извиняюсь, если я не вижу особого смысла!)

В следующем xaml первый бит работает, второй бит - это то, с чем я борюсь.

<TextBlock Text="{Binding Path=Header.Title}"/>

<TextBlock Text="{Binding Path={Binding Path=Header.KeyValuePath}}"/>

KeyValuePath может содержать что-то вроде «Vehicle.Registration» или «Supplier.Name» в зависимости от модели.

Может кто-нибудь указать мне правильное направление, пожалуйста? Любая помощь с благодарностью получена!

Ответы [ 2 ]

3 голосов
/ 10 июня 2009

Я не думаю, что это можно сделать в чистом XAML ... Path не является DependencyProperty (и в любом случае Binding не является DependencyObject), поэтому он не может быть целью привязки

Вместо этого вы можете изменить привязку в выделенном коде

1 голос
/ 30 июля 2009

Я не нашел способ сделать это в XAML, но я сделал это в коде позади. Вот подход, который я выбрал.

Во-первых, я хотел сделать это для всех предметов в ItemsControl. Итак, у меня был XAML вот так:

<ListBox x:Name="_events" ItemsSource="{Binding Path=Events}">
    <ListBox.ItemTemplate>
        <DataTemplate DataType="{x:Type Events:EventViewModel}">
            <TextBlock Name="ActualText" />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Затем в коде застройки я подписываюсь на ItemContainerGenerator:

InitializeComponent();
_events.ItemContainerGenerator.StatusChanged
     += OnItemContainerGeneratorStatusChanged;

Этот метод выглядит так:

private void OnItemContainerGeneratorStatusChanged(object sender, EventArgs e)
{
  if (_events.ItemContainerGenerator.Status!=GeneratorStatus.ContainersGenerated)
    return;

  for (int i = 0; i < _viewModel.Events.Count; i++)
  {
    // Get the container that wraps the item from ItemsSource
    var item = (ListBoxItem)_events.ItemContainerGenerator.ContainerFromIndex(i);
    // May be null if filtered
    if (item == null)
      continue;
    // Find the target
    var textBlock = item.FindByName("ActualText");
    // Find the data item to which the data template was applied
    var eventViewModel = (EventViewModel)textBlock.DataContext;
    // This is the path I want to bind to
    var path = eventViewModel.BindingPath;
    // Create a binding
    var binding = new Binding(path) { Source = eventViewModel };
    textBlock.SetBinding(TextBlock.TextProperty, binding);
  }
}

Если у вас есть только один элемент для установки привязки, то код был бы немного проще.

<TextBlock x:Name="_text" Name="ActualText" />

И в коде позади:

var binding = new Binding(path) { Source = bindingSourceObject };
_text.SetBinding(TextBlock.TextProperty, binding);

Надеюсь, это кому-нибудь поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...