我使用 DependencyProperty 创建了我的 UserControl。 当我在 TabControl.ContentTemplate 的 DataTemplate 中使用它时,数据绑定仍然粘在第一个选项卡对象上。 文本框数据绑定工作正常。
我想我错过了有关 UI 虚拟化的一些东西。我注意到所有选项卡都使用相同的模式按钮用户控件距离。
模式按钮.xaml
<UserControl x:Class="SSI.GUI.Controls.ProfileParameterButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Button x:Name="button" Margin="0" Padding="0" Click="button_Click"/>
</UserControl>
模式按钮.xaml.cs
public partial class ProfileParameterButton : UserControl
{
public ProfileParameterButton()
{
InitializeComponent();
}
#region ProfileParameter
public IProfileParameter? ProfileParameter
{
get { return GetValue(ProfileParameterProperty) is IProfileParameter value ? value : default; }
set { SetValue(ProfileParameterProperty, value); }
}
public static readonly DependencyProperty ProfileParameterProperty = DependencyProperty.Register(
nameof(ProfileParameter),
typeof(IProfileParameter),
typeof(ProfileParameterButton),
new FrameworkPropertyMetadata(
default,
FrameworkPropertyMetadataOptions.None,
new PropertyChangedCallback(OnProfileParameterChanged)
));
private static void OnProfileParameterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is ProfileParameterButton instance)
{
if (e.OldValue is INotifyPropertyChanged oldNPC)
{
oldNPC.PropertyChanged -= instance.ProfileParameter_PropertyChanging;
}
if (e.NewValue is IProfileParameter newNPC)
{
newNPC.PropertyChanged += instance.ProfileParameter_PropertyChanging;
}
instance.ProfileParameter = e.NewValue as IProfileParameter;
instance.ModeChanged();
}
else throw new InvalidOperationException();
}
private void ProfileParameter_PropertyChanging(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(IProfileParameter.Mode))
{
ModeChanged();
}
}
#endregion ProfileParameter
private void ModeChanged()
{
if (ProfileParameter == null)
{
button.ToolTip = Lang.Disabled;
button.IsEnabled = false;
}
else
{
button.ToolTip = ProfileParameter.Mode.ToString();
button.IsEnabled = ProfileParameter.CanReset();
}
}
private void button_Click(object sender, RoutedEventArgs e)
{
ProfileParameter?.Reset();
}
}
选项卡控件:
<TabControl ItemsSource="{Binding MyData}">
<TabControl.ContentTemplate>
<DataTemplate DataType="{x:Type viewmodelsData:MyData}">
<UniformGrid Columns="2">
<StackPanel>
<TextBlock Text="{Binding Material.Name}" FontWeight="Bold" FontSize="18"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!--Row-->
<controls:ModeButton Grid.Row="0" Grid.Column="1" Margin="2,2" ProfileParameter="{Binding Material.Parameter1}"/>
<TextBlock Grid.Row="0" Grid.Column="0" Margin="2,2" Text="{DynamicResource Lang.Material.Parameter1}" VerticalAlignment="Center"/>
<TextBox Grid.Row="0" Grid.Column="2" Margin="2,2" Text="{Binding Material.Parameter1.Value}" HorizontalContentAlignment="Right"/>
<!--Row-->
<controls:ModeButton Grid.Row="1" Grid.Column="1" Margin="2,2" ProfileParameter="{Binding Material.Parameter2}"/>
<TextBlock Grid.Row="1" Grid.Column="0" Margin="2,2" Text="{DynamicResource Lang.Material.Parameter2}" VerticalAlignment="Center"/>
<TextBox Grid.Row="1" Grid.Column="2" Margin="2,2" Text="{Binding Material.Parameter2.Value}" HorizontalContentAlignment="Right"/>
<TextBlock Grid.Row="1" Grid.Column="3" Margin="2,2" Text="[s]" VerticalAlignment="Center"/>
</UniformGrid>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>