如何在XAML中转换以访问子类属性 [英] How to cast in XAML to access sub-class properties
问题描述
在我的项目中,我列出了一个用作DataGrid数据源的 Units
的列表。 单位
类型有两种类型的子类, AUnits
和 BUnits
。列表中的每个单元
是 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认为我正在尝试访问不存在的属性。
我已阅读
如果我在代码隐藏中编写绑定而不是在XAML中,它也可以使用完全相同的方式:
colB.Binding = new Binding(B)
In my project I have a list of Units
which is being used as the source of data for a DataGrid. The Units
type has two types of subclasses, AUnits
and BUnits
. Each Unit
in the list is either an AUnit
or aBUnit
. My issue is when I try to bind to a property specific to one of the subclass unit types, XAML doesn't see it and I just get back 0's. Normally, if this was being done in C# I would just cast it and access the property, but I am not able to do that at this point in my code. The bindings are being created in C# like this:
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()
};
Where dgtc is a DataGridTextColumn. Unit.MaxDepthRelativeToEntry comes through as 0 because it is a property on the subclass of an AUnit
, so XAML thinks I am trying to access an non-existent property.
I have read this answer and so far I have tried some of the following syntaxes:
dgtc.Binding = new Binding("AUnit.MaxDepthRelativeToEntry")
dgtc.Binding = new Binding("Unit(MyNameSpace:AUnit).MaxDepthRelativeToEntry")
dgtc.Binding = new Binding("Unit(MyNameSpace:AUnit.MaxDepthRelativeToEntry)")
and was not able to get any of those to work. I have also tried doing this through a converter, but the issue is, I don't have the list of units available to me when I am constructing the DataGrid/ setting up the bindings/etc. so I am not able to grab the property out of the instance and return it. Does anyone know of any way that I can, preferably in XAML, get to the properties of a subclass type of the type I am binding to?
Edit:
My DataGrid has the following 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"
>
The ItemsSource
is set to the UnitStatusCollection
which is an ObservableCollection
of a class called UnitInfo
which holds a Unit
and a UnitStatus
. I need to access the property MaxDepthRelativeToEntry
in Unit
of UnitInfo
. But I need to be able to see Unit
as AUnit
If you are binding to a list of Unit
objects, then the DataContext
for your DataGridTextColumn
should be the AUnit
or BUnit
object itself, so your binding path should just be new Binding("MaxDepthRelativeToEntry")
.
You might get some kind of runtime warning for properties that only exist on one SubClass but not others, but it shouldn't throw an exception.
Here's a quick code sample to give an example :
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>
Code-Behind :
var test = new List<ClassA>();
test.Add(new ClassB() { A = "A", B = "B" });
test.Add(new ClassC() { A = "A", C = "C" });
dgTest.ItemsSource = test;
where the classes are defined as
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; }
}
Output :
It also works the exact same way if I write the binding in code-behind instead of in XAML :
colB.Binding = new Binding("B")
这篇关于如何在XAML中转换以访问子类属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!