3

DataGridComboBoxColumn をオートコンプリート コンボボックスとして使用したいと考えています。

私はそれを部分的に機能させています。Row が EditMode の場合、ComboBox にテキストを入力できます。また、ViewMode の場合、コントロールはテキストを返します。マウスのダブルクリックでラベル(テンプレート内)をEditModeにする方法のみ?

前もって、DataGridTemplateColumn コントロールを使用したくありません。DataGridComboBoxColumn のようにキーボードとマウスの入力 (タブ、矢印、編集/表示モード/ダブルクリックなど) を処理しないためです。

次のようになります。

アプリ

4

1 に答える 1

3

親の DataGrid へのリンクを取得する動作を に追加して修正し、TextBoxを呼び出して行を編集モードに設定しました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;
    }
}
于 2013-01-28T15:03:59.080 に答える