从 DataTemplate 中绑定到 TabItem Header
Binding to a TabItem Header from within DataTemplate
我正在尝试将 TabItem
中的 TextBox
的文本绑定到 TabItem
的 header,以便 header ] 和 TextBox 具有相同的内容(f.e。当 header 为“test”时,TextBox 也应显示“test”)。
TextBox
是 DataTemplate
的一部分,我将其用作 ContentTemplate
的 StaticResource
。 DataTemplate
工作正常,选项卡内的所有内容都按预期显示。只有 TextBox
是空的。我尝试了很多方法来定义 RelativeSource
,但到目前为止 none 一直有效。
<DataTemplate x:Key="myTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="..."/>
<Border BorderBrush="Black" BorderThickness="0 0 0.2 0"/>
<StackPanel Grid.Column="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="Name: "/>
<TextBox Grid.Column="1" Text="{Binding DataContext.Header,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabItem}}}"/>
<Button Grid.Column="3" Content="Speichern"/>
</Grid>
</StackPanel>
</Grid>
</DataTemplate>
编辑:
然后我使用这样的模板:
<TabControl>
<TabItem ContentTemplate="{StaticResource myTemplate}" Header="Test"/>
<TabItem Header="Tab 2"/>
<TabItem Header="Tab 3"/>
</TabControl>
@EldHasp Я отредактировал свой вопрос. Я не совсем понимаю, как работать с DataContext. Как добавить другое свойство для привязки?
通常为某些特定数据类型创建数据模板。
在 ContentControl(包括 TabItem)中,数据进入 Content 属性(通常来自 DataContext 属性)并且 ContentTemplate 中的模板指定其呈现。
这里是一个数据类型的例子,只有一个字符串 属性。
该示例使用 BaseInpc class.
using Simplified;
namespace TabItemHeaderBinding
{
public class TabItemContent : BaseInpc
{
private string _title;
public string Title { get => _title; set =>Set(ref _title, value); }
}
}
WPF 的典型实现是 MVVM 模式。
在这种情况下,您会在 TabControl 源中收到 collection 个元素 <TabControl ItemsSource =" {Binding CollectionProperty} "...>
。
在这种情况下,TabControl 会自动为每个项目创建一个 TabItem,在 DataContext 和 Content 中它将传递相应的 collection 项目。
元素模板、header 等中的绑定必须相对于此元素指定。
您没有 MVVM,所以我展示了一个简单的示例,对您的初始代码进行了最少的更改。
<Window x:Class="TabItemHeaderBinding.ThbWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TabItemHeaderBinding"
mc:Ignorable="d"
Title="ThbWindow" Height="450" Width="800">
<FrameworkElement.Resources>
<DataTemplate x:Key="myTemplate" DataType="{x:Type local:TabItemContent}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="/Febr20y;component/Image/block.png"/>
<Border BorderBrush="Black" BorderThickness="0 0 0.2 0"/>
<StackPanel Grid.Column="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="Name: "/>
<TextBox Grid.Column="1" Text="{Binding Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Button Grid.Column="3" Content="Speichern"/>
</Grid>
</StackPanel>
</Grid>
</DataTemplate>
</FrameworkElement.Resources>
<Grid>
<TabControl>
<TabItem ContentTemplate="{StaticResource myTemplate}"
Header="{Binding Title}"
Content="{Binding}">
<TabItem.DataContext>
<local:TabItemContent Title="TitleTest"/>
</TabItem.DataContext>
</TabItem>
<TabItem Header="Tab 2"/>
<TabItem Header="Tab 3"/>
</TabControl>
</Grid>
</Window>
Работает отлично
示例 MVVM 实现:
namespace TabItemHeaderBinding
{
public class TabItemImageContent : TabItemContent
{
private object _imageSource;
public object ImageSource { get => _imageSource; set =>Set(ref _imageSource, value); }
}
}
using System.Collections.ObjectModel;
namespace TabItemHeaderBinding
{
public class TabItemContentViewModel
{
public ObservableCollection<TabItemImageContent> Tabs { get; }
= new ObservableCollection<TabItemImageContent>()
{
new TabItemImageContent() {Title = "First", ImageSource="/Febr20y;component/Image/block.png"},
new TabItemImageContent() {Title = "Second", ImageSource="/Febr20y;component/Image/RAnimated1.gif"},
new TabItemImageContent() {Title = "Third", ImageSource="/Febr20y;component/Image/plus.jpg"},
};
}
}
<Window x:Class="TabItemHeaderBinding.ThbMvvmWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TabItemHeaderBinding"
mc:Ignorable="d"
Title="ThbMvvmWindow" Height="450" Width="800">
<FrameworkElement.Resources>
<DataTemplate x:Key="myTemplate" DataType="{x:Type local:TabItemImageContent}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="{Binding ImageSource}"/>
<Border BorderBrush="Black" BorderThickness="0 0 0.2 0"/>
<StackPanel Grid.Column="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="Name: "/>
<TextBox Grid.Column="1" Text="{Binding Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Button Grid.Column="3" Content="Speichern"/>
</Grid>
</StackPanel>
</Grid>
</DataTemplate>
</FrameworkElement.Resources>
<FrameworkElement.DataContext>
<local:TabItemContentViewModel/>
</FrameworkElement.DataContext>
<Grid>
<TabControl ItemsSource="{Binding Tabs}"
ContentTemplate="{DynamicResource myTemplate}">
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="Header" Value="{Binding Title}"/>
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
</Grid>
</Window>
我正在尝试将 TabItem
中的 TextBox
的文本绑定到 TabItem
的 header,以便 header ] 和 TextBox 具有相同的内容(f.e。当 header 为“test”时,TextBox 也应显示“test”)。
TextBox
是 DataTemplate
的一部分,我将其用作 ContentTemplate
的 StaticResource
。 DataTemplate
工作正常,选项卡内的所有内容都按预期显示。只有 TextBox
是空的。我尝试了很多方法来定义 RelativeSource
,但到目前为止 none 一直有效。
<DataTemplate x:Key="myTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="..."/>
<Border BorderBrush="Black" BorderThickness="0 0 0.2 0"/>
<StackPanel Grid.Column="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="Name: "/>
<TextBox Grid.Column="1" Text="{Binding DataContext.Header,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabItem}}}"/>
<Button Grid.Column="3" Content="Speichern"/>
</Grid>
</StackPanel>
</Grid>
</DataTemplate>
编辑: 然后我使用这样的模板:
<TabControl>
<TabItem ContentTemplate="{StaticResource myTemplate}" Header="Test"/>
<TabItem Header="Tab 2"/>
<TabItem Header="Tab 3"/>
</TabControl>
@EldHasp Я отредактировал свой вопрос. Я не совсем понимаю, как работать с DataContext. Как добавить другое свойство для привязки?
通常为某些特定数据类型创建数据模板。
在 ContentControl(包括 TabItem)中,数据进入 Content 属性(通常来自 DataContext 属性)并且 ContentTemplate 中的模板指定其呈现。
这里是一个数据类型的例子,只有一个字符串 属性。
该示例使用 BaseInpc class.
using Simplified;
namespace TabItemHeaderBinding
{
public class TabItemContent : BaseInpc
{
private string _title;
public string Title { get => _title; set =>Set(ref _title, value); }
}
}
WPF 的典型实现是 MVVM 模式。
在这种情况下,您会在 TabControl 源中收到 collection 个元素 <TabControl ItemsSource =" {Binding CollectionProperty} "...>
。
在这种情况下,TabControl 会自动为每个项目创建一个 TabItem,在 DataContext 和 Content 中它将传递相应的 collection 项目。
元素模板、header 等中的绑定必须相对于此元素指定。
您没有 MVVM,所以我展示了一个简单的示例,对您的初始代码进行了最少的更改。
<Window x:Class="TabItemHeaderBinding.ThbWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TabItemHeaderBinding"
mc:Ignorable="d"
Title="ThbWindow" Height="450" Width="800">
<FrameworkElement.Resources>
<DataTemplate x:Key="myTemplate" DataType="{x:Type local:TabItemContent}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="/Febr20y;component/Image/block.png"/>
<Border BorderBrush="Black" BorderThickness="0 0 0.2 0"/>
<StackPanel Grid.Column="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="Name: "/>
<TextBox Grid.Column="1" Text="{Binding Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Button Grid.Column="3" Content="Speichern"/>
</Grid>
</StackPanel>
</Grid>
</DataTemplate>
</FrameworkElement.Resources>
<Grid>
<TabControl>
<TabItem ContentTemplate="{StaticResource myTemplate}"
Header="{Binding Title}"
Content="{Binding}">
<TabItem.DataContext>
<local:TabItemContent Title="TitleTest"/>
</TabItem.DataContext>
</TabItem>
<TabItem Header="Tab 2"/>
<TabItem Header="Tab 3"/>
</TabControl>
</Grid>
</Window>
Работает отлично
示例 MVVM 实现:
namespace TabItemHeaderBinding
{
public class TabItemImageContent : TabItemContent
{
private object _imageSource;
public object ImageSource { get => _imageSource; set =>Set(ref _imageSource, value); }
}
}
using System.Collections.ObjectModel;
namespace TabItemHeaderBinding
{
public class TabItemContentViewModel
{
public ObservableCollection<TabItemImageContent> Tabs { get; }
= new ObservableCollection<TabItemImageContent>()
{
new TabItemImageContent() {Title = "First", ImageSource="/Febr20y;component/Image/block.png"},
new TabItemImageContent() {Title = "Second", ImageSource="/Febr20y;component/Image/RAnimated1.gif"},
new TabItemImageContent() {Title = "Third", ImageSource="/Febr20y;component/Image/plus.jpg"},
};
}
}
<Window x:Class="TabItemHeaderBinding.ThbMvvmWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TabItemHeaderBinding"
mc:Ignorable="d"
Title="ThbMvvmWindow" Height="450" Width="800">
<FrameworkElement.Resources>
<DataTemplate x:Key="myTemplate" DataType="{x:Type local:TabItemImageContent}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="{Binding ImageSource}"/>
<Border BorderBrush="Black" BorderThickness="0 0 0.2 0"/>
<StackPanel Grid.Column="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="Name: "/>
<TextBox Grid.Column="1" Text="{Binding Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<Button Grid.Column="3" Content="Speichern"/>
</Grid>
</StackPanel>
</Grid>
</DataTemplate>
</FrameworkElement.Resources>
<FrameworkElement.DataContext>
<local:TabItemContentViewModel/>
</FrameworkElement.DataContext>
<Grid>
<TabControl ItemsSource="{Binding Tabs}"
ContentTemplate="{DynamicResource myTemplate}">
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="Header" Value="{Binding Title}"/>
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
</Grid>
</Window>