Столбец 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"/> не ясно и потребует специальной документации.
  • Я не нашел никаких доказательств того, что эта рабочая комбинация является чем-то большим, чем чистое совпадение и может измениться в любое время с новой версией.

0 ответов

Другие вопросы по тегам