Столбец DataGridControl с ComboBox
Я использую DataGridControl
из расширенного набора инструментов WPC XCeed.
Моя цель - предоставить колонку с ComboBox
для выбора. Выбранное значение должно быть идентификатором, отображаемое значение - свойством Text, а текст также должен быть содержимым буфера обмена при копировании.
Мой вопрос: какой будет стандартный / надежный подход для реализации описанной функциональности?
Я нашел рабочее решение (см. Ниже), но я не понимаю, почему оно работает, в то время как аналогичные подходы не работают, и я чувствую, что использую какой-то взлом, который однажды развалится.
Вот MCVE функциональности.
Код
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var vm = new MainVM();
var sel1 = new SelectableItem { ID = 1, Text = "Text A" };
var sel2 = new SelectableItem { ID = 2, Text = "Text B" };
var sel3 = new SelectableItem { ID = 3, Text = "Text C" };
vm.Rows.Add(new RowVM(new SelectableItem[]
{
sel1,
sel2,
}));
vm.Rows.Add(new RowVM(new SelectableItem[]
{
sel2,
sel3,
}));
grid1.DataContext = vm;
}
}
public abstract class BaseVM : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChangedEvent([CallerMemberName]string prop = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(prop));
}
protected bool SetProperty<T>(ref T store, T value, [CallerMemberName]string prop = null)
{
if (!object.Equals(store, value))
{
store = value;
RaisePropertyChangedEvent(prop);
return true;
}
return false;
}
}
public class MainVM : BaseVM
{
private ObservableCollection<RowVM> _Rows = new ObservableCollection<RowVM>();
public ObservableCollection<RowVM> Rows
{
get { return _Rows; }
}
}
public class RowVM : BaseVM
{
public RowVM(IEnumerable<SelectableItem> items)
{
_SelectableItems = items;
}
private IEnumerable<SelectableItem> _SelectableItems;
public IEnumerable<SelectableItem> SelectableItems
{
get { return _SelectableItems; }
}
private int? _SelectedID;
public int? SelectedID
{
get { return _SelectedID; }
set
{
if (SetProperty(ref _SelectedID, value))
{
RaisePropertyChangedEvent("SelectedText");
}
}
}
public string SelectedText
{
get { return SelectableItems.Where(x => x.ID == SelectedID).Select(x => x.Text).FirstOrDefault(); }
}
}
public class SelectableItem
{
public int ID { get; set; }
public string Text { get; set; }
}
XAML (содержимое окна)
<Grid x:Name="grid1" xmlns:xd="http://schemas.xceed.com/wpf/xaml/datagrid">
<Grid.Resources>
<xd:DataGridCollectionViewSource x:Key="itemsViewSource" Source="{Binding Rows}"/>
</Grid.Resources>
<xd:DataGridControl AutoCreateColumns="False"
ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
UpdateSourceTrigger="CellEndingEdit">
<xd:DataGridControl.Columns>
<xd:Column FieldName="SelectedText" Title="Select by ComboBox">
<xd:Column.DisplayMemberBindingInfo>
<xd:DataGridBindingInfo Path="SelectedID"/>
</xd:Column.DisplayMemberBindingInfo>
<xd:Column.CellEditor>
<xd:CellEditor>
<xd:CellEditor.EditTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Path=DataContext.SelectableItems,RelativeSource={RelativeSource AncestorType={x:Type xd:DataRow}}}"
DisplayMemberPath="Text"
SelectedValuePath="ID"
IsEditable="True"
SelectedValue="{xd:CellEditorBinding}"/>
</DataTemplate>
</xd:CellEditor.EditTemplate>
</xd:CellEditor>
</xd:Column.CellEditor>
<xd:Column.CellContentTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=DataContext.SelectedText,RelativeSource={RelativeSource AncestorType={x:Type xd:DataRow}}}"/>
</DataTemplate>
</xd:Column.CellContentTemplate>
</xd:Column>
</xd:DataGridControl.Columns>
</xd:DataGridControl>
</Grid>
Интересные места / почему я чувствую, что подход хакерский:
- Если я не использую
DataGridCollectionViewSource
и вместо этого попробуйте напрямую связатьItemsSource="{Binding Rows}"
затем выбор значения ячейки и копирование выбранных строк в буфер обмена приводит к копированию идентификатора вместо текста. - Цель комбинации
<xd:Column FieldName="SelectedText">
а также<xd:DataGridBindingInfo Path="SelectedID"/>
не ясно и потребует специальной документации. - Я не нашел никаких доказательств того, что эта рабочая комбинация является чем-то большим, чем чистое совпадение и может измениться в любое время с новой версией.