我用DependencyProperty创建了我的UserControl。当我在TabControl.ContentTemplate的DataTemplate中使用它时,数据绑定仍然停留在第一个选项卡对象上。文本框数据绑定工作正常。
我想我错过了一些关于UI虚拟化的东西。我注意到所有的标签都使用相同的ModeButton用户控件。
ModeButton.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>
字符串
ModeButton.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:
<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>
型
1条答案
按热度按时间dxxyhpgq1#
声明
字符串
将新值分配给ProfileParameter属性,该属性将替换任何非TwoWay的Binding。
这个赋值无论如何都是无用的,因为PropertyChangedCallback是在属性值已经更改时调用的。不需要重新分配该值。
您的代码似乎还暗示
IProfileParameter
是从INotifyPropertyChanged
派生的,这使得PropertyChangedCallback中的所有类型检查都毫无意义。依赖属性系统保证
DependencyObject
参数始终是ProfileParameterButton,e.OldValue
和e.NewValue
属性始终是IProfileParameter
类型。因此,你可以这样写回调:
型