在DataGrid中使用DataGridComboBoxColumn作为autocompletecombobox

时间:2013-01-28 10:24:04

标签: wpf mvvm

我想将DataGridComboBoxColumn用作自动完成组合框。

我已经部分工作了。当Row在EditMode中时,我可以在ComboBox中键入文本,同样在ViewMode中,控件返回文本。只有通过鼠标双击如何将Label(在模板中)获取到EditMode?

在前面,我不想使用DataGridTemplateColumn控件,因为它只是不像DataGridComboBoxColumn那样处理键盘和鼠标输入(选项卡,箭头,编辑/查看模式/双击等)。

看起来像:

app

1 个答案:

答案 0 :(得分:3)

我修复了它向TextBox添加行为以获取指向父DataGrid的链接,然后通过调用BeginEdit()将行设置为编辑模式。

我使用的解决方案:

查看

<Window x:Class="WpfApplication1.MainWindow"
        xmlns:local="clr-namespace:WpfApplication1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Window.Resources>
        <local:BindingProxy x:Key="proxy" Data="{Binding}" />
    </Window.Resources>
    <Grid>
        <DataGrid ItemsSource="{Binding Model.Things}" Name="MyGrid" ClipboardCopyMode="IncludeHeader">
            <DataGrid.Resources>

            </DataGrid.Resources>
            <DataGrid.Columns>
                <DataGridComboBoxColumn Header="Object" MinWidth="140" TextBinding="{Binding ObjectText}" ItemsSource="{Binding Source={StaticResource proxy}, Path=Data.Model.ObjectList}" >
                    <DataGridComboBoxColumn.EditingElementStyle>
                        <Style TargetType="ComboBox">
                            <Setter Property="IsEditable" Value="True"/>
                            <Setter Property="Text" Value="{Binding ObjectText}"/>
                            <Setter Property="IsSynchronizedWithCurrentItem" Value="True" />
                        </Style>
                    </DataGridComboBoxColumn.EditingElementStyle>
                    <DataGridComboBoxColumn.ElementStyle>
                        <Style TargetType="ComboBox">
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate>
                                        <TextBox IsReadOnly="True" Text="{Binding Path=DataContext.ObjectText, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}}">
                                            <TextBox.Resources>
                                                <Style TargetType="{x:Type TextBox}">
                                                    <Setter Property="local:CellSelectedBehavior.IsCellRowSelected" Value="true"></Setter>
                                                </Style>
                                            </TextBox.Resources>
                                        </TextBox>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </DataGridComboBoxColumn.ElementStyle>
                </DataGridComboBoxColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

<强>模型

public class Model : BaseModel
{
    //List of objects for combobox
    private List<string> _objectList;
    public List<string> ObjectList { get { return _objectList; } set { _objectList = value; } }

    //Rows in datagrid
    private List<Thing> _things;
    public List<Thing> Things
    {
        get { return _things; }
        set { _things = value; OnPropertyChanged("Things"); }
    }
}

public class Thing : BaseModel
{
    //Text in combobox
    private string _objectText;
    public string ObjectText
    {
        get { return _objectText; }
        set { _objectText = value; OnPropertyChanged("ObjectText"); }
    }
}

<强>视图模型

public class ViewModel
{
    public Model Model { get; set; }

    public ViewModel()
    {
        Model = new WpfApplication1.Model();
        Model.ObjectList = new List<string>();
        Model.ObjectList.Add("Aaaaa");
        Model.ObjectList.Add("Bbbbb");
        Model.ObjectList.Add("Ccccc");
        Model.Things = new List<Thing>();
        Model.Things.Add(new Thing() { ObjectText = "Aaaaa" });
    }
}

<强>行为

public class CellSelectedBehavior
{
    public static bool GetIsCellRowSelected(DependencyObject obj) { return (bool)obj.GetValue(IsCellRowSelectedProperty); }

    public static void SetIsCellRowSelected(DependencyObject obj, bool value) { obj.SetValue(IsCellRowSelectedProperty, value); }

    public static readonly DependencyProperty IsCellRowSelectedProperty = DependencyProperty.RegisterAttached("IsCellRowSelected",
      typeof(bool), typeof(CellSelectedBehavior), new UIPropertyMetadata(false, OnIsCellRowSelected));

    static void OnIsCellRowSelected(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
    {
        TextBox item = depObj as TextBox;
        if (item == null)
            return;

        if (e.NewValue is bool == false)
            return;

        if ((bool)e.NewValue)
            item.MouseDoubleClick += SelectRow;
        else
            item.MouseDoubleClick -= SelectRow;
    }

    static void SelectRow(object sender, EventArgs e)
    {
        TextBox box = sender as TextBox;
        var grid = box.FindAncestor<DataGrid>();
        grid.BeginEdit();
    }
}

帮助程序(查找DataGrid)

public static class Helper
{
    public static T FindAncestor<T>(this DependencyObject current) where T : DependencyObject
    {
        current = VisualTreeHelper.GetParent(current);
        while (current != null)
        {
            if (current is T)
            {
                return (T)current;
            }
            current = VisualTreeHelper.GetParent(current);
        };
        return null;
    }
}