WPF绑定:属性包含值的路径

4

我有一个扩展器,在顶部栏中有几个TextBlocks,用于提供标题和关键信息。

理想情况下,我希望设置到关键信息的路径,但是我无法弄清如何将绑定的路径绑定到另一个路径(如果我表达不清楚,我很抱歉!)

在以下xaml中,第一部分可以工作,第二部分是我正在努力解决的问题。

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

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

根据模型,KeyValuePath 可能包含类似于 "Vehicle.Registration" 或者 "Supplier.Name" 的内容。

请问有人可以指点我正确的方向吗?非常感谢您的帮助!


我也在尝试做同样的事情。我想知道是否可以使用自定义标记扩展来帮助实现,但由于Path不是依赖属性,我无法想象这将如何工作。 - Drew Noakes
2个回答

3

我认为在纯XAML中无法完成这个操作...Path不是一个DependencyProperty(而且Binding也不是一个DependencyObject),所以它不能成为绑定的目标

你可以在代码后台修改绑定方式


1

我还没有找到在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);

希望这能帮助到某个人。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接