2015-10-15 18 views
5

私はDataGridDataGridTemplateColumnComboBoxを持っています。私は、それは明らかに私のコレクションの新しいインスタンスを作成していないとだけ空白のリストが表示されます、空白行のComboBoxをクリックWPF DataGridシングルクリックして新しいアイテムを作成する

<DataGrid GridLinesVisibility="All" AutoGenerateColumns="False" ItemsSource="{Binding TestItemCollection}"> 
     <DataGrid.Columns> 
      <DataGridTemplateColumn Width="*" Header="Test Column"> 
       <DataGridTemplateColumn.CellTemplate> 
        <DataTemplate> 
         <ComboBox Width="150" 
            HorizontalAlignment="Left" 
            ItemsSource="{Binding TestChildCollection}" /> 
        </DataTemplate> 
       </DataGridTemplateColumn.CellTemplate> 
      </DataGridTemplateColumn> 
     </DataGrid.Columns> 
    </DataGrid> 



public ObservableCollection<TestClass> TestItemCollection { get; set; } = new ObservableCollection<TestClass> 
    { 
     new TestClass(), 
     new TestClass(), 
     new TestClass(), 
    }; 

    public class TestClass 
    { 
     public ObservableCollection<string> TestChildCollection { get; set; } = new ObservableCollection<string> 
     { 
      "First test item", "Second test item" , "Third test item" , "Fourth test item" 
     }; 
    } 

enter image description here

私は空の行のスペースにダブルクリックする必要があります。

enter image description here

だけにして、私はComboBox内のデータを得るでしょう。私は、空白行のシングルクリックでCombobox内のデータを取得できますか

enter image description here

答えて

1

あなたは空白行の単一クリックでComboBoxにデータを取得する必要がある場合、私はあなたのComboBoxDropDownOpenedイベントにコマンドを「添付」するCaliburn.Microを使用することをお勧めします。ここで

サンプル:すべてのXAML

の最初の
<Window x:Class="WpfApplication1.MainView" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:cal="http://www.caliburnproject.org" 
     Title="MainView" Height="600" Width="600" 
     Name="_window"> 

    <DataGrid GridLinesVisibility="All" AutoGenerateColumns="False" ItemsSource="{Binding TestItemCollection}"> 
     <DataGrid.Columns> 
      <DataGridTemplateColumn Width="*" Header="Test Column"> 
       <DataGridTemplateColumn.CellTemplate> 
        <DataTemplate> 
         <ComboBox Width="150" 
            HorizontalAlignment="Left" 
            ItemsSource="{Binding TestChildCollection}" 
            cal:Message.Attach="[Event DropDownOpened] = [Action Choose($dataContext)]"/> 
        </DataTemplate> 
       </DataGridTemplateColumn.CellTemplate> 
      </DataGridTemplateColumn> 
     </DataGrid.Columns> 
    </DataGrid> 

その後のViewModel:

public class MainViewModel : Caliburn.Micro.PropertyChangedBase 
{ 
    public MainViewModel() 
    { 
     TestItemCollection = new ObservableCollection<TestClass> 
     { 
      new TestClass(), 
      new TestClass(), 
      new TestClass(), 
     }; 
    } 

    public void Choose(object data) 
    { 
     if (!(data is TestClass)) 
     { 
      TestItemCollection.Add(new TestClass()); 
     } 
    } 

    public ObservableCollection<TestClass> TestItemCollection { get; set; } 
} 

は私のサンプルでTestClassコードは、あなたが書いたことと同じであることをご検討ください。もちろん、Caliburn.Microで作業するためにアプリケーションを設定する必要があります(実行方法がわからない場合はdocumentationを読むことができます)。

Caliburn.Microを使用したくない場合(または使用できない場合)は、System.Windows.Interactivityライブラリを使用して同じ結果を得ることができます(下記の私の編集を参照)。

コードを試してください:クリックすると新しい行が自動的に作成されます。 私はそれがあなたを助けることを願っています。

EDIT:

<Window x:Class="WpfApplication1.MainView" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
     xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 
     Title="MainView" Height="600" Width="600" 
     Name="_window"> 

    <DataGrid GridLinesVisibility="All" AutoGenerateColumns="False" ItemsSource="{Binding TestItemCollection}"> 
     <DataGrid.Columns> 
      <DataGridTemplateColumn Width="*" Header="Test Column"> 
       <DataGridTemplateColumn.CellTemplate> 
        <DataTemplate> 
         <ComboBox Width="150" 
            HorizontalAlignment="Left" 
            ItemsSource="{Binding TestChildCollection}"> 
          <i:Interaction.Triggers> 
           <i:EventTrigger EventName="DropDownOpened"> 
            <ei:CallMethodAction MethodName="ChooseWithInteraction" 
                 TargetObject="{Binding ElementName=_window, Path=DataContext}" /> 
           </i:EventTrigger> 
          </i:Interaction.Triggers> 
         </ComboBox> 
        </DataTemplate> 
       </DataGridTemplateColumn.CellTemplate> 
      </DataGridTemplateColumn> 
     </DataGrid.Columns> 
    </DataGrid> 

</Window> 

あなたが見ることができるように:あなたはCaliburn.Microを使用できない場合は、あなただけの、このようにMAINVIEWのXAMLを変更する必要がSystem.Windows.Interactivity

代替ソリューション、私はちょうどへの参照を追加しました。Microsoft.Expression.InteractionsSystem.Windows.Interactivityライブラリ。その後、私はEventTriggerCallMethodActionComboBoxに追加しました。このようにして

public void ChooseWithInteraction(object sender, EventArgs args) 
{ 
    object data = ((ComboBox)sender).DataContext; 
    if (!(data is TestClass)) 
    { 
     TestItemCollection.Add(new TestClass()); 
    } 
} 

をあなたが私の同じ動作を得ることができます。MainViewModelあなたが(もちろんあなたは、単にコードに追加することができます)ChooseWithInteraction 1でChoose方法を置き換えることができ、今

Caliburnを使用しないで

+0

私はあなたの考えを持っています。これはDataContextでTestClassの新しいインスタンスを作成しますが、データでコンボボックスを開けません。以前は行を選択する前に結論を出していましたが、それだけでComboboxはデータを取得します。 – Spirosi

+0

これは正しい@Spirosiではありません。 .NET 4とCaliburn.Micro 2.0.2でコードをテストしました。最後のコンボボックスをクリックすると、「挿入行」内に挿入されたコンボボックスが** _データ(つまり、「最初のテスト項目」、「2番目のテスト項目」、「3番目のテスト項目」、第4の試験項目」)。あなたは別の行動を取っていますか? –

+0

私はそれをインタラクティブでのみテストしました。 Cliburnで試してみる。 – Spirosi

1

私は、次の2つの手順を実行して、目的の機能を達成できる解決策を見つけました。

ステップ1:あなたはDataGridTemplateColumnためCellEditingTemplateを指定し、DataGridTemplateColumn.CellTemplateためfalseIsHitTestVisibleを設定する必要があります。これにより、DataGridCell(例:ComboBox)がクリックされたときにUIが編集モードに入るよう強制され、結果としてコレクションの新しいインスタンスが作成されます。

<DataGrid Grid.Row="0" 
       SelectionUnit="Cell" 
       DataGridCell.Selected="DataGridCell_GotFocus" 
       GridLinesVisibility="All" AutoGenerateColumns="False" ItemsSource="{Binding TestItemCollection}"> 
     <DataGrid.Columns> 
      <DataGridTemplateColumn Width="*" Header="Test Column"> 
       <DataGridTemplateColumn.CellTemplate> 
        <DataTemplate> 
         <ComboBox Width="150" IsHitTestVisible="False" 
           HorizontalAlignment="Left" 
           ItemsSource="{Binding TestChildCollection}" 
           SelectedItem="{Binding SelectedTestItem}" /> 
        </DataTemplate> 
       </DataGridTemplateColumn.CellTemplate> 
       <DataGridTemplateColumn.CellEditingTemplate> 
        <DataTemplate> 
         <ComboBox Width="150" 
           HorizontalAlignment="Left" 
           ItemsSource="{Binding TestChildCollection}" 
            SelectedItem="{Binding SelectedTestItem}"/> 
        </DataTemplate> 
       </DataGridTemplateColumn.CellEditingTemplate> 
      </DataGridTemplateColumn> 
     </DataGrid.Columns> 
    </DataGrid> 

は、ステップ2:次に、あなたのDataGridためxamlは次のように変更する必要があります

public class TestClass 
{ 
    public ObservableCollection<string> TestChildCollection { get; set; } 

    // keeps the selected value of each ComboBox 
    public string SelectedTestItem { get; set; } 

    public TestClass() 
    { 
     TestChildCollection = new ObservableCollection<string> {"First test item", "Second test item" , "Third test item" , "Fourth test item" }; 
    } 

} 

:そのためには、まず、各ComboBoxの選択された値を保つために、あなたのTestClassでプロパティを定義する必要があります:上記のxamlのように、SelectionUnitCellに設定され、DataGridCell.Selectedのイベントハンドラも定義されています。イベントハンドラのコードは以下の通りである:これは、すべての時間あなたはそれが編集モードに入りますDataGridCellをクリックすることを確認します

private void DataGridCell_GotFocus(object sender, RoutedEventArgs e) 
    { 
     if (e.OriginalSource.GetType() == typeof(DataGridCell)) 
     { 
      DataGrid dataGrid = (DataGrid)sender; 
      dataGrid.BeginEdit(e); 
     } 
    } 

。したがって、新しく作成されたDataGridRowの中にComboBoxを開こうとするたびに、クリックが1つ少なくなる必要があります。

+1

1つ少なくてもまだ1つだけです:)ドロップダウンを開くには2回のクリックが必要です。しかし、とにかくおかげで、あなたのソリューションは私に合っています。 – Spirosi

+0

あなたが正しいです、最初のクリックは新しいセルを選択するためのもので、2回目のクリックはドロップダウンを開きます。 –

関連する問題