2012-04-14 6 views
0

私はいくつかのオブジェクトを含むdCB_Propsと呼ばれるユーザコントロールを持っています。最も重要なのは、Observable CollectionにバインドされたComboBoxです。コレクションは任意のオブジェクトを取ることができますが、通常はEditDeleteItemというUserControlが使用されます。 dCB_PropsEditDeleteItemItemsTemplateとして使用するように設定しましたが、イベントは発生しません。一方、EditDeleteItemのインスタンスを追加すると、イベントが発生します。私はEditDeleteItemが他のコントロールをホストするので、この方法でアイテムを追加することはできません。別のDataTemplatesを使用する必要があります。DataTemplateからカスタムルーティングイベントを呼び出すにはどうすればよいですか?

EditDeleteItemには、EditClickDeleteClickという2つのルーテッドイベントがあります。

コレクションが変更されると、追加されたアイテムがタイプEditDeleteItemであるかどうかをチェックするイベントが発生します。そうであれば、前述の2つのイベントにハンドラを追加します。 EditDeleteClickのためのXAMLの

パート:dCB_PropsためのXAMLの

<WrapPanel x:Name="wp" HorizontalAlignment="Right" Visibility="Hidden" VerticalAlignment="Center" Margin="0,0,5,0"> 
    <Button x:Name="PART_Edit" Width="20" Height="20" Content="{DynamicResource dPen}" Style="{DynamicResource dTranspButton}" Click="btnEdit_Click"/> 
    <Button x:Name="PART_Delete" Width="20" Height="20" Content="{DynamicResource dCross}" Style="{DynamicResource dTranspButton}" Click="btnDelete_Click"/> 
</WrapPanel> 
<Label Content="{TemplateBinding Content}" Margin="2,0,45,0" Padding="0,0,0,0" HorizontalAlignment="Left" VerticalContentAlignment="Center"/> 

パート:

<ComboBox HorizontalContentAlignment="Stretch" x:Name="PART_cb" Background="Transparent" Margin="0,0,0.367,0" d:LayoutOverrides="HorizontalAlignment" ItemsSource="{Binding Items, ElementName=dcb}" IsDropDownOpen="{Binding IsDropDownOpen,ElementName=dcb, Mode=TwoWay}" Grid.ColumnSpan="3" Style="{DynamicResource DaisyComboBox}" /> 
<Button x:Name="PART_Edit" Width="20" Height="20" Content="{DynamicResource dPen}" Visibility="Hidden" Style="{DynamicResource dTranspButton}" Margin="2.581,1.48,17.778,-1.48" Grid.Column="1" Click="btnEdit_Click"/> 
<Button x:Name="PART_Delete" Width="20" Height="20" Content="{DynamicResource dCross}" Visibility="Hidden" Margin="22.602,1.48,-2.243,-1.48" Style="{DynamicResource dTranspButton}" Grid.Column="1" Click="btnDelete_Click"/> 
<Button x:Name="PART_Add" Content="+" Grid.Column="3" Margin="0,0,0,0" Style="{DynamicResource dTranspButton}" Click="btnAdd_Click"/> 

上記の二つはただのオブジェクトのためのコードであることに注意してください、私は列の定義を残してきました、イベントトリガーなどがdCB_Props.xaml.csコードの一部は、

です

public partial class dCB_Props : UserControl 
{ 
    public dCB_Props() 
    { 
     this.InitializeComponent(); 
     Items= new ObservableCollection<object>(); 
     Items.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Items_CollectionChanged); 
    } 

    void Items_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
    { 
     if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add) 
     { 
      foreach (var o in e.NewItems) 
      { 
       if (o.GetType() == typeof(EditDeleteItem)) 
       { 
        EditDeleteItem itm = (EditDeleteItem)o; 
        itm.EditClick += new RoutedEventHandler(ItemEdit_Click); 
        itm.DeleteClick += new RoutedEventHandler(ItemDelete_Click); 
       } 
      } 
     } 
    } 
    ...//I've left some code here since I don't deem it's that important for the situation 
    private void ItemEdit_Click(object sender, RoutedEventArgs e) 
    { 
     DependencyObject d = GetTemplateChild("PART_cb"); 
     if (d == null) return; 
     ComboBox cb = (ComboBox)d; 
     if (cb.SelectedItem != null) RaiseEvent(new RoutedEventArgs(EditClickEvent, e.OriginalSource)); 
    } 
} 

EditDeleteItemのアイテムを追加し、ItemTemplateというラベルのプロパティがdCB_Propsのものである場合は、上のように動作します。これは、私がEditDeleteItemのContentTemplateにItemTemplateを設定した場合にも機能します。しかし、前述したように、私は異なるデータテンプレートを使用する必要があるので、すべてのデータテンプレートをリソースディクショナリに配置し、テンプレートセレクタを使用する必要があると仮定します。

データテンプレート:

<DataTemplate x:Shared="false" x:Key="TagTemplate"> 
     <local:EditDeleteItem x:Name="edItem"> 
      <local:EditDeleteItem.Content> 
       <StackPanel> 
        <TextBlock Text="{Binding Path=Content.Label}"/> 
        <CheckBox Content="Isolated" IsChecked="{Binding Content.IsIsolated}"/> 
        <CheckBox Content="Match Case" IsChecked="{Binding Content.MatchCase}"/> 
        <CheckBox Content="Include" IsChecked="{Binding Content.Include}"/> 
       </StackPanel> 
      </local:EditDeleteItem.Content> 
     </local:EditDeleteItem> 
</DataTemplate> 

私は、コマンドバインディングを使用する必要があると考えています。しかし、CommandBindingをどこに置くべきかはわかりませんし、使用方法もわかりませんが、1ページまたは2ページを読んだことがあります。 ItemTemplateには使用されている場合Items_CollectionChangedでのサブスクリプションが発生したことがないので

おかげで、 ハッサン

答えて

0

イベントは、解雇されていますが、それらをキャッチしていません。

ItemsControl(とComboBox)がItemsSourceとどのように連携するかを理解する必要があります。 ItemsControlはItemContainerGeneratorを使用してビジュアルツリーを設定します。 ItemsSourceの各アイテムは、ContentControlから派生したコンテナにラップされます。 itemはContentとして設定され、ItemTemplateはContentTemplateなどに設定されます。 EditDeleteItemをItemTemplateに入れると、それはビジュアルツリーの一部になりますが、アイテムにはなりません。そのため、e.NewItemsにはEditDeleteItemがなく、サブスクリプションもありません。

正しい方法は、前述のとおりです。あなたは、2つのコマンドを宣言する必要があります。

public class EditDeleteItem : UserControl 
{ 
    ... 
    public static readonly RoutedUICommand EditCommand = new RoutedUICommand(...); 
    public static readonly RoutedUICommand DeleteCommand = new RoutedUICommand(...); 
    ... 
} 

は今テンプレートの一部を次のようになります。

<WrapPanel ...> 
    <Button ... Command="{x:Static EditDeleteItem.EditCommand}"/> 
    <Button ... Command="{x:Static EditDeleteItem.DeleteCommand}"/> 
</WrapPanel> 

その後、dCB_Propsにコマンドバインディングを追加します。

public partial class dCB_Props : UserControl 
{ 
    static dCB_Props() 
    { 
     ... 
     CommandManager.RegisterClassCommandBinding(
      typeof(dCB_Props), 
      new CommandBinding(EditDeleteItem.EditCommand, OnEditCommandExecuted)); 
     CommandManager.RegisterClassCommandBinding(
      typeof(dCB_Props), 
      new CommandBinding(EditDeleteItem.DeleteCommand, OnDeleteCommandExecuted)); 
     ... 
    } 
    ... 
} 

あなたはOnEditCommandExecutedを実装する必要があり、 EditDeleteItemからの対応するコマンドを処理するためにOnDeleteCommandExecuted。

私はあなたの質問を正しく理解していただきたいと思います;)

関連する問題