Używam doskonałego zestawu narzędzi MVVM Light. Moje ViewModel uwidacznia:Korzystanie z WPF DataGridComboBoxColumn z MVVM - powiązanie z właściwością w ViewModel
public const string CourtCodesTypeCourtPropertyName = "CourtCodesTypeCourt";
private List<CourtType> _courtCodesTypes = new List<CourtType>();
public List<CourtType> CourtCodesTypeCourt
{
get
{
return _courtCodesTypes;
}
set
{
if (_courtCodesTypes == value)
{
return;
}
var oldValue = _courtCodesTypes;
_courtCodesTypes = value;
// Update bindings and broadcast change using GalaSoft.MvvmLight.Messenging
RaisePropertyChanged(CourtCodesTypeCourtPropertyName, oldValue, value, true);
}
}
public const string CourtCodesPropertyName = "CourtCodes";
private List<Court> _courtCodes = null;
public List<Court> CourtCodes
{
get
{
return _courtCodes;
}
set
{
if (_courtCodes == value)
{
return;
}
var oldValue = _courtCodes;
_courtCodes = value;
// Update bindings and broadcast change using GalaSoft.Utility.Messenging
RaisePropertyChanged(CourtCodesPropertyName, oldValue, value, true);
}
}
The View ma DataGrid:
<DataGrid
ItemsSource="{Binding CourtCodes, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
AutoGenerateColumns="False"
AlternatingRowBackground="{DynamicResource OffsetBrown}"
AlternationCount="1" Margin="45,0">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Abbreviation, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Header="Abbreviation"
Width="25*" />
<DataGridTextColumn Binding="{Binding FullName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Header="Court"
Width="75*" />
<DataGridComboBoxColumn Header="CourtType"
ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.CourtCodesTypeCourt} TextBinding="{Binding CourtTypeDescription}""/>
</DataGrid.Columns>
</DataGrid>
DataGrid ma ItemsSource, jak widać, od CourtCodes. Chcę, aby kolumna CourtType była rozwijana wszystkich wyliczonych CourtTypes, które są zawarte w CourtCodesTypeCourt. Dla mojego życia nie mogę zapełnić pola DataGridComboBoxColumn czymkolwiek. Obecna nieudana próba próbuje użyć RelativeSource ... co robię źle?
Ponadto nie działa, dwa błędy, które widzę są:
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Window', AncestorLevel='1''. BindingExpression:Path=DataContext.CourtCodesTypeCourt; DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=38771709); target property is 'ItemsSource' (type 'IEnumerable')
i
System.Windows.Data Error: 40 : BindingExpression path error: 'CourtCodesTypeCourt' property not found on 'object' ''Court' (HashCode=38141773)'. BindingExpression:Path=CourtCodesTypeCourt.CourtTypeDescription; DataItem='Court' (HashCode=38141773); target element is 'ComboBox' (Name=''); target property is 'Text' (type 'String')
Dzięki za twoją pomoc, Kent ... to zdecydowanie mnie zbliża. Zgadzam się ... to niedorzeczne, że trzeba uciec się do tego rodzaju składni. Walczę. Teraz mam obiekty CourtType wypełniające DataGridComboBoxColumn, ale w ramach tej składni, jak kontrolować wyświetlany tekst? Obecnie wyświetla nazwę typu, a nie właściwość CourtTypeDescription. Po drugie, doceniam Twoją opinię na temat najlepszych praktyk ...Mógłbym, być może błędnie, odnieść wrażenie, że MVVM Light Toolkit przekształcił utworzone przez mvvminpc właściwości w ObservableCollections ... czy ja też na tym nie polega? –
Zignoruj pytanie o najlepszą praktykę ObservableCollections ... Przetestowałem to nieco i widzę wartość. Możliwość dołączenia do zdarzenia CollectionChanged wydaje się warta tego na własną odpowiedzialność. Mogę użyć przeskoków na składni DataGridComboBoxColumn ... jeszcze raz dziękuję za pomoc! –
@Mike: powinieneś być w stanie ustawić 'DisplayMemberPath =" CourtTypeDescription "' na twoim 'DataGridComboBoxColumn'. –