Значения DataGridComboBoxColumn из пользовательского класса - PullRequest
0 голосов
/ 21 декабря 2011

У меня есть класс CommentsData, и он используется для загрузки, манипулирования и сохранения значений в DataGrid. Я хочу, чтобы поле «Состояние» в классе отображалось в виде раскрывающегося списка в сетке. Значения комментария должны быть заполнены только один раз. Я перепробовал много вариантов, но это не работает. Комбо пусто. Мне нужно иметь возможность заполнять значения в комбо, и когда выбор изменяется, значение должно оставаться там и не исчезать.

Вот Xaml для сетки (Обновлено 2)

<DataGrid Grid.Row="2" AutoGenerateColumns="False"  Height="Auto" HorizontalAlignment="Stretch" Name="grdComments" VerticalAlignment="Stretch" CanUserAddRows="True" CanUserDeleteRows="True" BeginningEdit="grdComments_BeginningEdit" InitializingNewItem="grdComments_InitializingNewItem" PreviewKeyDown="grdComments_PreviewKeyDown" SizeChanged="grdComments_SizeChanged">
  <DataGrid.Columns>
    <DataGridTextColumn Binding="{Binding Path=Author}" Header="Author" />
    <DataGridTemplateColumn Header="Status" >
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <ComboBox  ItemsSource="{Binding UserValues}" DisplayMemberPath="UserStatus" SelectedValuePath="UserStatus" SelectedValue="{Binding Status, UpdateSourceTrigger=PropertyChanged}" />
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
    <DataGridTextColumn Binding="{Binding Path=Comment}" Header="Comment" Width="570" />
  </DataGrid.Columns>

Вот код для класса CommentData (Обновлено 2)

public class CommentsData 
{

    public string Author { get; set; }
    public string Status { get; set; }
    public string Comment { get; set; }
    public string Username { get; set; }

    public ObservableCollection<StatusValue> UserValues { get; set; }

    public CommentsData()
    {
        UserValues = new ObservableCollection<StatusValue>();

        UserValues.Add(new StatusValue("New"));
        UserValues.Add(new StatusValue("Open"));
        UserValues.Add(new StatusValue("ReOpen"));
        UserValues.Add(new StatusValue("Closed"));

    }

}

public class StatusValue
{
    public string UserStatus { get; set; }

    public StatusValue (string value)
    {
        UserStatus = value;
    }
}

Вот код, где инициализируется список комментариев

private List<CommentsData> _commentsList;

private void InitializeObjects()
{
        _commentsList = new List<CommentsData>();
        grdComments.ItemsSource = _commentsList;

}

вышеприведенный код работает благодаря всем отзывам

Ответы [ 3 ]

1 голос
/ 21 декабря 2011

В вашем коде я пропускаю несколько вещей

Во-первых, ваш класс не реализует INotifyPropertyChanged .Это означает, что если свойство изменяется на CommentData, оно не сообщает измененному пользовательскому интерфейсу, поэтому пользовательский интерфейс не обновляется для отображения нового значения.

Во-вторых, вы сообщаете своему ComboBox что есть свойство с именем Status для каждого элемента, и используйте его как ComboBoxItem.Value, однако это свойство не существует в StatusValue.Измените его на UserStatus, которое является допустимым свойством StatusValue.

SelectedValuePath="UserStatus"

И, наконец, вам не следует заново создавать элементы ComboBox для каждого элемента.Вместо этого создайте коллекцию где-то еще выше в иерархии ViewModel или сделайте ее статическим ресурсом.

Например, если класс, который содержит вашу коллекцию CommentsData, также содержит вашу коллекцию StatusValues, вы можете использовать привязку RelativeSource для привязки к ней следующим образом:

ItemsSource="{Binding 
    RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
    Path=DataContext.UserValues}"
1 голос
/ 21 декабря 2011

Как указано в статье MSDN о DataGridComboBoxColumn , чтобы заполнить раскрывающийся список, необходимо сначала установить свойство ItemsSource для ComboBox, используя один из следующих параметров:

  • Статический ресурс.
  • Объект x: Статический код.
  • Встроенная коллекция типов ComboBoxItem.

Если вы хотите связать ComboBox.ItemsSource с объектомсвойство, проще использовать DataGridTemplateColumn вот так:

<DataGridTemplateColumn Header="Status">
     <DataGridTemplateColumn.CellTemplate>
         <DataTemplate>
              <ComboBox ItemsSource="{Binding UserValues}" DisplayMemberPath="UserStatus" SelectedValuePath="UserStatus" SelectedValue="{Binding Status, UpdateSourceTrigger=PropertyChanged}" />
         </DataTemplate>
     </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
0 голосов
/ 21 декабря 2011

Вот что я бы использовал вместо вашей DataGridComboboxColumn:

<DataGridTemplateColumn>
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <ComboBox ItemsSource="{Binding UserValues}" SelectedItem="{Binding Status}" DisplayMemberPath="UserStatus" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

Также CommentsData.Status должен иметь тип StatusValue, а не string, чтобы вы могли связать SelectedItem на нем.

...