Как отобразить свойство DataGrid с помощью комбинированного окна / раскрывающегося списка, который изменяется в зависимости от ввода другого свойства текстового поля - PullRequest
0 голосов
/ 01 мая 2020

У меня есть DataGrid, который привязан к списку, как показано ниже, который имеет различные свойства. У меня есть 2 требования, с которыми я борюсь.

<DataGrid  ItemsSource="{Binding Path=VariedObjectList}" 
AutoGeneratingColumn="OnAutoGeneratingColumn" x:Name="dataGridView"
                          SelectionMode="Single" AutoGenerateColumns="true" CanUserAddRows="true"  CanUserDeleteRows="true />
  1. Для определенного значения c в текстовом поле property1 список элементов, отображаемых в property2, должен динамически изменяться. Так, например, здесь, если «Value» имеет значение, скажем, 2, то «ValueRange» должен отображать выпадающий список с элементами «2-5» и «5.81-6.6» в качестве элементов списка, а если «Значение» равно 8, то список изменяется на => 7,9-8,8; 8.81-11.2 и так далее, как на картинке ниже.

Как мне этого добиться? Я хотел бы сохранить привязку ко всей коллекции, как указано выше. Xaml.

enter image description here

 public class VariedObjectList
{
    public Modes ModeType { get; set; }
    public int Value{ get; set; }
    public <dataType??> ValueRange { get; set; } // not sure what should be the type for ValueRange

}
public enum Mode
    {
        ModeSlow = 0,
        ModeFast = 1,
        ModeNeutral = 2,
        ModeNone = 3
    }


Если моим свойством «ModeType» является «ModeSlow» или «ModeFast», тогда «ValueRange» должен быть dropDownlist. Если ModeType имеет значение «ModeNeutral», тогда ValueRange должен принять textBox. Как мне этого добиться?

Я изменил код в соответствии с рекомендациями Кейта, и, хотя большинство моих изменений работают, у меня проблема в следующих областях

(я ) я не мог заставить работать редактируемое поле со списком. Он принимает значение, когда я набираю текст, но как только мой фокус покидает поле, текст исчезает, и для введенного текста никогда не происходит связывание с SelectedValueRange. Но когда есть список, и если я выбираю любое значение из списка, он привязывается к «SelectedValueRange», но не для ввода текста.

(ii) ModeType - это enum, когда новая строка вводится по умолчанию, я хочу для отображения «ModeSlow», но он пуст. Кроме того, если я обновляю одну строку, все предыдущие строки также обновляются с последним поведением value.its странно, но я знаю, что что-то упустил.

public class VariedObjectList : INotifyPropertyChanged
{
    public Mode ModeType { get; set; } = Mode.ModeSlow;
    private int val;
    public int Value {
            get { return val; }
            set
            {
                val = value;

                OnPropertyChanged("Value");
                SetValueRangeList();
            }
        }
    public List<strings> ValueRange { get; set; } 
    public string SelectedValueRange {get; set;}

}

ниже обновлено xaml

Я устанавливаю ObjectDataProvider для Enum

<Window.Resources>
        <ObjectDataProvider x:Key="EnumProvider" MethodName="GetValues"
                            ObjectType="{x:Type System:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="local:Modes"/>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
</Window.Resources >

<DataGrid x:Name="dataGridView" Grid.Row="0" DataGridCell.Selected="DataGridGotFocus" ItemsSource="{Binding VariedObjectList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" AutoGenerateColumns="False" 
                               CanUserDeleteRows="true"  SelectionMode="Single" CanUserAddRows="True" VerticalScrollBarVisibility="Auto" ScrollViewer.CanContentScroll="True">

                    <DataGrid.Columns>
                        <DataGridTemplateColumn  Header=" ModeType " >
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <ComboBox ItemsSource="{Binding Source={StaticResource EnumProvider}}"
                                              SelectedItem="{Binding Path= ModeType 
, UpdateSourceTrigger=LostFocus, Mode=TwoWay}" />
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                        </DataGridTemplateColumn>
                        <DataGridTextColumn Header="Value" Binding="{Binding Value, UpdateSourceTrigger=LostFocus}"/>
                        <DataGridTemplateColumn  Header="ValueRange" >
                            <DataGridTemplateColumn.CellEditingTemplate>
                                <DataTemplate>
                                    <ComboBox IsEditable="True" SelectedValue="{Binding SelectedValueRange, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding Path= ValueRange }" /> 
                                </DataTemplate>
                            </DataGridTemplateColumn.CellEditingTemplate>
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding SelectedValueRange, UpdateSourceTrigger=LostFocus, Mode=TwoWay}"/>

                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                        </DataGridTemplateColumn>
                    </DataGrid.Columns>
                </DataGrid>


Может кто-нибудь указать, что мне не хватает в примере код? Спасибо.

1 Ответ

0 голосов
/ 01 мая 2020

Давайте начнем с класса VariedObjectList:

  • Поскольку ValueRange будет меняться, и вы хотите, чтобы пользовательский интерфейс обновлялся с ним, VariedObjectList будет иметь для реализации интерфейса INotifyPropertyChanged .

  • Типом для ValueRange может быть любой обобщенный c набор int. Я бы рекомендовал объявить свойство как IList<int>, потому что оно дает вам много места для использования различных коллекций, если вам нужно.

  • В ModeType.set, наряду с повышением PropertyChanged вам нужно создать или получить список значений, которые вы хотите отобразить для этого Mode, а затем присвоить этому списку ValueRange.

Теперь для DataGrid :

Если вы хотите изменить поведение столбца ValueRange в зависимости от ModeType, вам придется отказаться от AutoGenerateColumns="true" Вместо этого вы будете явно определять столбцы между <DataGrid.Columns> tags.

Я бы рекомендовал DataGridTemplateColumn для столбца ValueRange. CellEditingTemplate будет содержать ComboBox с ItemsSource={Binding ValueRange}. Вы можете применить Style к ComboBox, который изменит IsEditable в зависимости от значения ModeType. Это позволит вам настроить способность пользователя вводить текст, который не соответствует ни одному элементу в списке.

Для редактируемого ComboBox вам придется использовать свойство Text. SelectedValue и SelectedItem работают только при выборе элемента из выпадающего меню, но не при вводе пользовательского текста.

...