如何在 WPF 中绑定到具有附加属性的不同抽象类实现而不导致绑定失败

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

我从

abstract
UtilityElectricityConsumptionModel
实现了类UtilityNaturalGasConsumptionModel
UtilityConsumptionModel
UtilityNaturalGasConsumptionModel
只是添加了额外的
ConversionCoefficient
属性。

我通过

ConversionCoefficient
DataGrid
绑定到
DataGridTemplateColumn
中的
Trigger
。我最初没有遇到任何绑定失败,但自从我开始滚动
DataGrid
后,我就遇到了绑定失败。有没有办法避免这些绑定失败?

<!--  Conversion Coefficient  -->
<DataGridTemplateColumn Width="100" Header="Conversion Coefficient">

    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>

            <TextBlock>

                <TextBlock.Style>

                    <Style TargetType="{x:Type TextBlock}">

                        <Setter Property="HorizontalAlignment" Value="Stretch" />
                        <Setter Property="Background" Value="{StaticResource PrimarySolidColorBrush}" />

                        <Style.Triggers>

                            <DataTrigger Binding="{Binding Source}" Value="{x:Static models:UtilitySource.NaturalGas}">

                                <Setter Property="Padding" Value="2,0,2,0" />
                                <Setter Property="HorizontalAlignment" Value="Right" />
                                <Setter Property="Background" Value="Transparent" />
                                <Setter Property="Text" Value="{Binding ConversionCoefficient, StringFormat='0.00'}" />

                            </DataTrigger>

                        </Style.Triggers>

                    </Style>

                </TextBlock.Style>

            </TextBlock>

        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>

</DataGridTemplateColumn>
wpf binding abstract-class
1个回答
0
投票

我尝试进行快速模拟来重现您的问题,但失败了。我哪里做错了?我们做了什么不同的事情?它在我这边滚动得很好。

<Window x:Class="abstract_class_binding_issue.MainWindow"
        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:abstract_class_binding_issue"
        xmlns:models="clr-namespace:abstract_class_binding_issue.Models"
        mc:Ignorable="d"
        Title="MainWindow" Height="250" Width="400">
    <Window.Resources>
        <SolidColorBrush x:Key="PrimarySolidColorBrush" Color="LightGray"/>
    </Window.Resources>
    <Window.DataContext>
        <models:MainViewModel/>
    </Window.DataContext>
    <Grid>
        <DataGrid ItemsSource="{Binding UtilityConsumptions}" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTemplateColumn Width="100" Header="Conversion Coefficient">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock>
                                <TextBlock.Style>
                                    <Style TargetType="{x:Type TextBlock}">
                                        <Setter Property="HorizontalAlignment" Value="Stretch" />
                                        <Setter Property="Background" Value="{StaticResource PrimarySolidColorBrush}" />
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding Source}" Value="{x:Static models:UtilitySource.NaturalGas}">
                                                <Setter Property="Padding" Value="2,0,2,0" />
                                                <Setter Property="HorizontalAlignment" Value="Right" />
                                                <Setter Property="Background" Value="Transparent" />
                                                <Setter Property="Text" Value="{Binding ConversionCoefficient, StringFormat='0.00'}" />
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </TextBlock.Style>
                            </TextBlock>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTextColumn Header="Utility Type" Binding="{Binding Source}" Width="200"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>
namespace abstract_class_binding_issue
{
    public partial class MainWindow : Window
    {
        public MainWindow() =>  InitializeComponent();
    }
    namespace Models
    {
        class MainViewModel
        {
            public IList UtilityConsumptions { get; } = new ObservableCollection<UtilityConsumptionModel>();

            public MainViewModel()
            {
                object animation = UtilitySource.Electricity;
                var s = $"{animation.GetType().Name}.{animation}";


                for (int i = 0; i < 100; i++) // Add enough items for scrolling
                {
                    if (i % 2 == 0)
                    {
                        UtilityConsumptions.Add(new UtilityNaturalGasConsumptionModel { ConversionCoefficient = i * 1.5 });
                    }
                    else
                    {
                        UtilityConsumptions.Add(new UtilityElectricityConsumptionModel());
                    }
                }
            }
        }
        abstract class UtilityConsumptionModel : INotifyPropertyChanged
        {
            protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) =>
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            public event PropertyChangedEventHandler? PropertyChanged;
        }
        class UtilityElectricityConsumptionModel : UtilityConsumptionModel
        {
            public UtilitySource Source => UtilitySource.Electricity;
        }
        class UtilityNaturalGasConsumptionModel : UtilityConsumptionModel
        {
            public UtilitySource Source => UtilitySource.NaturalGas;
            public double ConversionCoefficient
            {
                get => _conversionCoefficient;
                set
                {
                    if (!Equals(_conversionCoefficient, value))
                    {
                        _conversionCoefficient = value;
                        OnPropertyChanged();
                    }
                }
            }
            double _conversionCoefficient = default;
        }
        enum UtilitySource
        {
            Electricity,
            NaturalGas
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.