#c# #wpf #data-binding #datatemplate
#c# #wpf #привязка к данным #табличка данных
Вопрос:
Я обнаружил, что при использовании ContentTemplate / DataTemplate в WPF TabControl мои привязки больше не будут работать.
Я привел небольшой пример для иллюстрации:
<Window x:Class="HAND.BindingExample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="BindingExample" Height="506" Width="656"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
>
<Grid>
<TabControl HorizontalAlignment="Left" Height="381" VerticalAlignment="Top" Width="608">
<TabItem Header="TabItem">
<Label Content="{Binding Path=myString}"/>
</TabItem>
<TabItem Header="TabItem">
<TabItem.ContentTemplate>
<DataTemplate>
<Label Content="{Binding Path=myString}"/>
</DataTemplate>
</TabItem.ContentTemplate>
</TabItem>
</TabControl>
</Grid>
</Window>
Tab1 работает как ожидалось, Tab2 пуст.
код, лежащий в основе:
using System.Windows;
namespace HAND
{
public partial class BindingExample : Window
{
public string myString { get; set; }
public BindingExample()
{
myString = "Hello Stackoverflow";
InitializeComponent();
}
}
}
Ответ №1:
Вы неправильно используете ContentTemplate
свойство. Со страницы ContentControl.ContentTemplate
свойств в MSDN:
Получает или задает шаблон данных, используемый для отображения содержимого ContentControl.
Поэтому при настройке этого свойства вам также необходимо установить Content
свойство для какого-либо источника данных:
<TabControl>
<TabItem Header="TabItem">
<Label Content="{Binding Path=myString}"/>
</TabItem>
<TabItem Header="TabItem" Content="{Binding Path=myString}">
<TabItem.ContentTemplate>
<DataTemplate>
<Label Content="{Binding}" />
</DataTemplate>
</TabItem.ContentTemplate>
</TabItem>
</TabControl>
Комментарии:
1. Тот же вывод, что и у Miiite. Также большое вам спасибо за хорошее объяснение!
2. почему вам нужно установить Content=»{Путь привязки=mystring}» в <TabItem>, А затем также установить Content=»{Привязка}» в <Label>? В этом примере это не кажется необходимым для TabItem. ContentTemplate вообще? Разве это не работало бы так же хорошо без шаблона? Я пытаюсь понять шаблоны и как я могу привязать другие свойства метки к родительскому DataContext … спасибо!
3. Мы привязываем
myString
свойство кContent
свойству, чтобы придать ему некоторое значение. Здесь это значение представляет собой всего лишь одну строку, но оно могло быть объектом с другими свойствами. ВContentTemplate
мы сообщаем ему, какую часть объекта с привязкой к данным мы хотим отобразить вLabel
. В этом случае мы хотим выполнить привязку ко всему объекту string, поэтому мы используем{Binding}
для этого.4. Примечательно, однако: пример будет работать только для привязок, доступных только для чтения — если вы измените
Label
наTextBox
, myString никогда не будет записан обратно.
Ответ №2:
<TabItem Content="{Binding myString}" Header="TabItem">
<TabItem.ContentTemplate>
<DataTemplate>
<Label Content="{Binding}" />
</DataTemplate>
</TabItem.ContentTemplate>
</TabItem>
Но, чтобы вы знали, привязывать окно к самому себе — это просто не выход.
Я не знаю, сделали ли вы это только для примера, но если нет, попробуйте создать надлежащую ViewModel для привязки вашего окна 😉
Комментарии:
1. У меня это запущено на моей машине. Возможно, он не запускается, когда вы привязываете окно к самому себе, чего я не делал.
2. Спасибо! Это работает для моего примера. Я использую другой класс привязки в своей реальной программе, используя шаблон MVVM. Я все еще не понимаю, почему ваш код работает, а мой нет. Теперь я попытаюсь применить решение из примера к своему приложению.
3. Шеридан опубликовал ответ с тем же кодом XAML, что и у меня, но с лучшим объяснением того, как работает ContentTemplate. Это должно помочь вам понять это
4. Да, спасибо вам обоим!
5. привет, ваш ответ сработал для меня, неправильно протестирован. внесите правку в ваш ответ, я верну отрицательный результат