DataTemplate 中的用户控件依赖属性绑定 (TabControl.ContentTemplate)

问题描述 投票:0回答:0

我使用 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>
c# wpf xaml data-binding user-controls
© www.soinside.com 2019 - 2024. All rights reserved.