Я не нашел способ сделать это в 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);
Надеюсь, это кому-нибудь поможет.