如何使用GridViewComboBoxColumn并允许用户编辑?

时间:2018-02-24 07:58:15

标签: wpf xaml gridview wpfdatagrid

我需要提供一个WPF GridView,其中一列是Combobox,用户可以从列表中选择一个值或输入新值,因此我将IsComboBoxEditable设置为{ {1}}但问题是如果用户键入的值不在true中,则当ItemsSource失去焦点时,文本为空。

  

注意:输入新值时,我不想要这个值   添加到Combobox。我只需要在行中保存ItemsSource值   这与它有关。

我还需要DropDownOpened事件来填充它的ItemsSource。

这是我的代码:

string

<telerik:GridViewDataColumn Header="Description"> <telerik:GridViewDataColumn.CellTemplate> <DataTemplate> <telerik:RadComboBox IsEditable="True" ItemsSource="{Binding Descriptions}" Text="{Binding Description1,Mode=TwoWay}" DropDownOpened="descriptionRadComboBox_DropDownOpened"/> </DataTemplate> </telerik:GridViewDataColumn.CellTemplate> </telerik:GridViewDataColumn> Description1属性,string是在运行时填充的Descriptions列表。(当string事件发生时)

2 个答案:

答案 0 :(得分:6)

就像你提到的那样,你的目标只是“可编辑的ComboBox”。 (当然,您不希望将新项目添加到ItemsSource

<telerik:GridViewDataColumn UniqueName="description1"  Header="Description">
    <telerik:GridViewDataColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Description1}"></TextBlock>
        </DataTemplate>
    </telerik:GridViewDataColumn.CellTemplate>
    <telerik:GridViewDataColumn.CellEditTemplate>
        <DataTemplate>
            <telerik:RadComboBox Name="SLStandardDescriptionsRadComboBox" IsEditable="True" 
                                                         ItemsSource="{Binding DataContext.SLStandardDescriptions, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" 
                                                        DisplayMemberPath="SLStandardDescriptionTitle" DropDownOpened="Description_DropDownOpened">
            </telerik:RadComboBox>
        </DataTemplate>
    </telerik:GridViewDataColumn.CellEditTemplate>

</telerik:GridViewDataColumn>

Codebehinde:

private void RadGridView_CellEditEnded(object sender, GridViewCellEditEndedEventArgs e)
{
    if (e.Cell.Column.UniqueName == "description1")
    {
        RadComboBox combo = e.Cell.ChildrenOfType<RadComboBox>().FirstOrDefault();
        if (combo != null)
        {
            List<Description> comboItems = combo.ItemsSource as List<Description>;

            string textEntered = e.Cell.ChildrenOfType<RadComboBox>().First().Text;

            bool result = comboItems.Contains(comboItems.Where(x => x.DescriptionTitle == textEntered).FirstOrDefault());
            if (!result)
            {
                comboItems.Add(new Description { DescriptionTitle = textEntered });
                combo.SelectedItem = new Description { DescriptionTitle = textEntered };
            }
            if (_viewModel.AccDocumentItem != null)
            {
                if (e.Cell.Column.UniqueName == "description1")
                    _viewModel.AccDocumentItem.Description1 = textEntered;
            }
        }
    }
}

答案 1 :(得分:1)

以下是.net DataGrid控件的解决方案:

  <DataGrid ItemsSource="{Binding Path=Items}" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Path=Title}" ></DataGridTextColumn>
            <DataGridComboBoxColumn SelectedValueBinding="{Binding ComboItem.ID}"  DisplayMemberPath="ComboTitle"  SelectedValuePath="ID">
                <DataGridComboBoxColumn.ElementStyle>
                    <Style TargetType="{x:Type ComboBox}">
                        <Setter Property="ItemsSource" Value="{Binding Path=DataContext.ComboItems, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
                    </Style>
                </DataGridComboBoxColumn.ElementStyle>
                <DataGridComboBoxColumn.EditingElementStyle>                        
                    <Style TargetType="{x:Type ComboBox}">
                        <Setter Property="ItemsSource" Value="{Binding Path=DataContext.ComboItems, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
                        <Setter Property="IsEditable" Value="True" />
                    </Style>
                </DataGridComboBoxColumn.EditingElementStyle>                    
            </DataGridComboBoxColumn>
        </DataGrid.Columns>
    </DataGrid>

当然,您也可以使用Telerik DataGrid控件执行此操作。

这是我的ViewModel:

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;  

            ComboItems = new ObservableCollection<ComboItem>()
            {
                new ComboItem(){ID=1,ComboTitle="ComboItem1"},
                new ComboItem(){ID=2,ComboTitle="ComboItem2"},
                new ComboItem(){ID=3,ComboTitle="ComboItem3"}
            };    
            Items = new ObservableCollection<Item>()
            {
                new Item(){ID=1,Title="Item1",ComboItem=ComboItems[0]},
                new Item(){ID=2,Title="Item2",ComboItem=ComboItems[1]},
                new Item(){ID=3,Title="Item3",ComboItem=ComboItems[2]}
            };                
        }    
        public ObservableCollection<Item> Items { get; set; }
        public ObservableCollection<ComboItem> ComboItems { get; set; }               
    }

    public class Item
    {
        public int ID { get; set; }
        public string Title { get; set; }
        public ComboItem ComboItem { get; set; }
    }

    public class ComboItem
    {
        public int ID { get; set; }
        public string ComboTitle { get; set; }
    }