2016-07-07 21 views
0

In meinem Projekt habe ich eine Liste von Units, die als die Quelle der Daten für ein DataGrid verwendet wird. Der Typ Units hat zwei Arten von Unterklassen: AUnits und BUnits. Jede Unit in der Liste ist entweder eine AUnit oder eine BUnit. Mein Problem ist, wenn ich versuche, an eine Eigenschaft zu binden, die für einen Unterklassen-Einheitentyp spezifisch ist, XAML sieht es nicht und ich bekomme nur Nullen zurück. Normalerweise, wenn dies in C# gemacht wird, würde ich es einfach umwandeln und auf die Eigenschaft zugreifen, aber das kann ich an dieser Stelle in meinem Code nicht tun. Die Bindungen werden in C# wie folgt erstellt:Wie in XAML für den Zugriff auf Unterklasse Eigenschaften umgewandelt werden

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() 
}; 

Wo dgtc ein Datagridtextcolumn ist. Unit.MaxDepthRelativeToEntry kommt als 0 daher, weil es eine Eigenschaft der Unterklasse AUnit ist, also denkt XAML, dass ich versuche, auf eine nicht existierende Eigenschaft zuzugreifen.

Ich habe this answer gelesen und bisher habe ich einige der folgenden Syntaxen versucht:

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

und war nicht in der Lage zu arbeiten, um irgendwelche denen zu erhalten. Ich habe auch versucht, dies durch einen Konverter zu tun, aber das Problem ist, ich habe nicht die Liste der Einheiten, die mir zur Verfügung stehen, wenn ich das DataGrid erstelle/die Bindungen aufstelle/etc. daher kann ich die Eigenschaft nicht aus der Instanz herausholen und zurückgeben. Kennt irgendjemand irgendwie, dass ich, vorzugsweise in XAML, zu den Eigenschaften eines Unterklasse-Typs des Typs gelangen kann, an den ich binde?

Edit:

My Datagrid hat die folgende 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" 
       > 

Die ItemsSource zum UnitStatusCollection gesetzt, der eine ObservableCollection einer Klasse UnitInfo genannt, die eine Unit und UnitStatus hält. Ich muss auf die Eigenschaft MaxDepthRelativeToEntry in Unit von UnitInfo zugreifen. Aber ich muß in der Lage sein zu sehen, Unit als AUnit

Antwort

2

Wenn Sie auf eine Liste von Unit Objekten verbindlich sind, dann ist die DataContext für Ihre DataGridTextColumn sollte das AUnit oder BUnit Objekt selbst sein, so dass Ihre Bindung Pfad sollte nur sein new Binding("MaxDepthRelativeToEntry").

Sie könnten eine Art Laufzeitwarnung für Eigenschaften erhalten, die nur für eine SubClass existieren, aber nicht für andere, aber es sollte keine Ausnahme ausgelöst werden.

Hier ist ein schnelles Codebeispiel ein Beispiel zu geben:

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; 

, wo die Klassen als

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; } 
} 
definiert sind

Ou tput:

enter image description here

Es ist auch genau die gleiche Art und Weise funktioniert, wenn ich schreibe, die in Bindungs ​​Code-Behind statt in XAML:

colB.Binding = new Binding("B") 
+0

ich schon erwähnt, vernachlässigt, dass es eine Wrapper-Klasse ist um meine Units, und das ist meine ItemsSource wie folgt in XAML gesetzt: 'ItemsSource =" {Binding UnitStatusCollection, Mode = TwoWay} "'. Kann ich einfach etwas tun wie: 'dgtc.Binding = new Binding (" UnitInfo.AUnit.MaxDepthRelativeToEntry ")', wenn UnitInfo die Wrapper-Klasse ist? Ich werde die Frage auch aktualisieren – KSF

+1

@KSF Meine Antwort würde sich nicht ändern, obwohl Sie eine weitere Eigenschaft zum Bindungspfad hinzufügen müssten. Wenn Sie beispielsweise an eine Sammlung von UnitInfo-Objekten gebunden sind und jedes Objekt eine Unit-Eigenschaft besitzt, die entweder vom Typ AUnit oder BUnit sein könnte, wäre Ihre Bindung nur {Binding Unit. MaxDepthRelativeToEntry} 'oder' new Binding ("Unit.MaxDepthRelativeToEntry") '. Der Text in der Zeichenkette sollte mit dem übereinstimmen, wie die normale C# aussehen würde ... Wenn Sie 'UnitStatusCollection [0] .Unit.MaxDepthRelativeToEntry' schreiben könnten, dann sollte Ihre Bindung 'Unit.MaxDepthRelativeToEntry' sein. – Rachel

+0

@KSF Wenn Sie still sind unklar, bitte bearbeiten Sie Ihre Frage, um die Struktur Ihrer Objektmodelle einzuschließen. Das definiert, was der Bindungspfad sein sollte. – Rachel