【问题标题】:How to cast in XAML to access sub-class properties如何在 XAML 中进行强制转换以访问子类属性
【发布时间】:2016-11-10 02:46:52
【问题描述】:

在我的项目中,我有一个 Units 列表,它被用作 DataGrid 的数据源。 Units 类型有两种类型的子类,AUnitsBUnits。列表中的每个Unit 要么是AUnit,要么是BUnit。我的问题是当我尝试绑定到特定于子类单元类型之一的属性时,XAML 看不到它,我只是返回 0。通常,如果这是在 C# 中完成的,我只会强制转换它并访问该属性,但此时我无法在我的代码中执行此操作。绑定是在 C# 中创建的,如下所示:

 dgtc.Header = Properties.Resources.MaxPressure;
 dgtc.MinWidth = 25;
 dgtc.Width = Properties.Settings.Default.MaxPressureColumnWidth;
 dgtc.IsReadOnly = true;
 dgtc.Binding = new Binding("Unit.MaxDepthRelativeToEntry")
 {
     Converter = new DistanceUnitsConverter()
 };

其中 dgtc 是一个 DataGridTextColumn。 Unit.MaxDepthRelativeToEntry 为 0,因为它是 AUnit 的子类上的属性,因此 XAML 认为我正在尝试访问不存在的属性。

我已经阅读了this answer,到目前为止我已经尝试了以下一些语法:

dgtc.Binding = new Binding("AUnit.MaxDepthRelativeToEntry")
dgtc.Binding = new Binding("Unit(MyNameSpace:AUnit).MaxDepthRelativeToEntry")
dgtc.Binding = new Binding("Unit(MyNameSpace:AUnit.MaxDepthRelativeToEntry)")

并且无法使任何这些工作。我也尝试通过转换器执行此操作,但问题是,当我构建 DataGrid/设置绑定/等时,我没有可用的单元列表。所以我无法从实例中获取属性并将其返回。有谁知道我可以通过任何方式(最好是在 XAML 中)获取我绑定到的类型的子类类型的属性?

编辑:

我的 DataGrid 具有以下 XAML:

<DataGrid x:Name="JobListView"
              AutoGenerateColumns="False"
              ItemsSource="{Binding UnitStatusCollection, Mode=TwoWay}"
              CanUserDeleteRows="False"
              Style="{StaticResource JobGridViewStyle}"
              SelectedItem="{Binding JobsListViewSelectedUnitInfo, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
              Utility:DataGridColumnsBehavior.BindableColumns="{Binding DataGridColumns}"
              ContextMenu="{StaticResource ListViewContextMenu}"
              Margin="10,5,10,2"
              Grid.Row="2"
              SelectionMode="Single"
              SelectionUnit="FullRow"
              HorizontalAlignment="Stretch"
              HorizontalContentAlignment="Stretch"
              RowStyle="{StaticResource DataGridRowStyle}"
              CellStyle="{StaticResource DataGridCellStyle}"
              AlternationCount="2"
              HorizontalScrollBarVisibility="Visible"
              VerticalScrollBarVisibility="Visible"
              CanUserResizeRows="False"
              HorizontalGridLinesBrush="#d6d6d6"
              VerticalGridLinesBrush="#d6d6d6"
              Background="#EAEAEA"
              >

ItemsSource 设置为UnitStatusCollection,这是一个名为UnitInfo 的类的ObservableCollection,该类包含UnitUnitStatus。我需要访问UnitInfoUnit 中的属性MaxDepthRelativeToEntry。但我需要能够将Unit 视为AUnit

【问题讨论】:

    标签: c# wpf xaml data-binding


    【解决方案1】:

    如果您要绑定到Unit 对象列表,那么您的DataGridTextColumnDataContext 应该是AUnitBUnit 对象本身,因此您的绑定路径应该只是new Binding("MaxDepthRelativeToEntry")

    对于只存在于一个子类上而不存在于其他子类上的属性,您可能会收到某种运行时警告,但它不应引发异常。

    这里有一个快速的代码示例来举例:

    XAML:

    <DataGrid x:Name="dgTest" AutoGenerateColumns="False" CanUserAddRows="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="A" Binding="{Binding A}" />
            <DataGridTextColumn Header="B" Binding="{Binding B}" />
            <DataGridTextColumn Header="C" Binding="{Binding C}" />
        </DataGrid.Columns>
    </DataGrid>
    

    代码隐藏:

    var test = new List<ClassA>();
    test.Add(new ClassB() { A = "A", B = "B" });
    test.Add(new ClassC() { A = "A", C = "C" });
    dgTest.ItemsSource = test;
    

    类的定义位置

    public class ClassA
    {
        public string A { get; set; }
    }
    
    public class ClassB : ClassA
    {
        public string B { get; set; }
    }
    
    public class ClassC : ClassA
    {
        public string C { get; set; }
    }
    

    输出:

    如果我在代码隐藏而不是 XAML 中编写绑定,它的工作方式也完全相同:

    colB.Binding = new Binding("B")
    

    【讨论】:

    • 我没有提到我的 Units 周围有一个包装类,并且我的 ItemsSource 是在 XAML 中设置的,如下所示:ItemsSource="{Binding UnitStatusCollection, Mode=TwoWay}"。如果 UnitInfo 是包装类,我是否应该能够做类似的事情:dgtc.Binding = new Binding("UnitInfo.AUnit.MaxDepthRelativeToEntry")?我也会更新问题
    • @KSF 我的答案不会改变,尽管您必须在绑定路径中再添加一个属性。例如,如果您要绑定到UnitInfo 对象的集合,并且每个对象都有一个Unit 属性,该属性可以是AUnitBUnit,那么您的绑定将只是{Binding Unit.MaxDepthRelativeToEntry} 或@ 987654340@。字符串中的文本应该与普通 c# 的样子相匹配......如果你可以写 UnitStatusCollection[0].Unit.MaxDepthRelativeToEntry,那么你的绑定应该是 Unit.MaxDepthRelativeToEntry
    • @KSF 如果您仍然不清楚,请编辑您的问题以包含对象模型的结构。这就是定义绑定路径的内容。
    猜你喜欢
    • 2014-07-05
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-09
    • 1970-01-01
    相关资源
    最近更新 更多