Привязка к табличке данных WPF

#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. привет, ваш ответ сработал для меня, неправильно протестирован. внесите правку в ваш ответ, я верну отрицательный результат