自定义类中的 DataGridComboBoxColumn 值

发布于 2024-12-22 16:12:42 字数 2327 浏览 3 评论 0原文

我有一个 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;

}

上面的代码正在运行 感谢所有反馈

I have a CommentsData class and this is used to load, manipulate and save values in a DataGrid. I want to make the Status field in the class shown as a dropdown in the grid. The Comment values need to be populated one time only. I have tried many variations but this does not work. The combo is blank. I need to be able to populate the values in the combo and when the selection changes the value should remain there and not dissappear.

Here is the Xaml for the Grid (Updated 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>

Here is the code for the CommentData class (Updated 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;
    }
}

Here is the code where the comments list is initialized

private List<CommentsData> _commentsList;

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

}

The above code is working Thanks to all the feedback

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

二手情话 2024-12-29 16:12:42

正如 MSDN 文章中所述,有关 DataGridComboBoxColumn 填充下拉列表中,您必须首先使用以下选项之一设置 ComboBox 的 ItemsSource 属性:

  • 静态资源。
  • 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>

As stated on MSDN article about DataGridComboBoxColumn to populate the drop-down list, you must first set the ItemsSource property for the ComboBox by using one of the following options:

  • A static resource.
  • An x:Static code entity.
  • An inline collection of ComboBoxItem types.

If you want to bind ComboBox.ItemsSource to object property, it`s easier to use DataGridTemplateColumn like this:

<DataGridTemplateColumn Header="Status">
     <DataGridTemplateColumn.CellTemplate>
         <DataTemplate>
              <ComboBox ItemsSource="{Binding UserValues}" DisplayMemberPath="UserStatus" SelectedValuePath="UserStatus" SelectedValue="{Binding Status, UpdateSourceTrigger=PropertyChanged}" />
         </DataTemplate>
     </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
风铃鹿 2024-12-29 16:12:42

我发现您的代码中缺少一些内容

首先,您的类没有实现 INotifyPropertyChanged。这意味着,如果 CommentData 上的属性发生更改,它不会告诉 UI 该属性已更改,因此 UI 不会更新以显示新值。

其次,您告诉您的 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}"

There are a few things that I see missing from your code

First off, your class doesn't implement INotifyPropertyChanged. That means, if a property changes on CommentData, it doesn't tell the UI that is has changed, so the UI doesn't update to display the new value.

Second, you are telling your ComboBox that there is a property called Status on each item, and use it as the ComboBoxItem.Value, however this property does not exist on StatusValue. Change it to refer to UserStatus, which is a valid property on StatusValue.

SelectedValuePath="UserStatus"

And last of all, you really shouldn't be re-creating the ComboBox items on each item. Instead, create the collection somewhere further up in the ViewModel hierarchy, or make it a static resource.

For example, if the class which contains your collection of CommentsData also contained your collection of StatusValues, you could use a RelativeSource binding to bind to it like this:

ItemsSource="{Binding 
    RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
    Path=DataContext.UserValues}"
森林迷了鹿 2024-12-29 16:12:42

下面是我将使用的 DataGridComboboxColumn:

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

另外 CommentsData.Status 应该是 StatusValue 类型,而不是 string,以便您可以绑定SelectedItem 就可以了。

Here is what I would use instead your DataGridComboboxColumn:

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

Also CommentsData.Status should be of type StatusValue, not string, so that you can bind the SelectedItem on it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文