2016-03-28 28 views
2

私はこれを多くのグーグルで解決しようとしていますが、残念ながら私はこの問題を解決できません。私が読むほど、混乱してしまいます。伝統的なイベントをカスタムコントロールに追加する

カスタムコントロールとしてオートコンプリートテキストボックスを作成したいと考えています。

マイCustomControl:背後に

<UserControl x:Class="ApplicationStyling.Controls.AutoCompleteTextBox" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:ApplicationStyling.Controls" 
      mc:Ignorable="d" 
      d:DesignHeight="300" 
      d:DesignWidth="300" 
      Name="AutoCompleteBox"> 
    <Grid> 
     <TextBox Grid.Row="3" 
       Style="{DynamicResource InputBox}" 
       x:Name="SearchBox" 
       Text="{Binding Text}" 
       TextChanged="{Binding ElementName=AutoCompleteBox, Path=TextChanged}"/> 

     <ListBox x:Name="SuggestionList" 
       Visibility="Collapsed" 
       ItemsSource="{Binding ElementName=AutoCompleteTextBox, Path=SuggestionsSource}" 
       SelectionChanged="{Binding ElementName=AutoCompleteBox, Path=SelectionChanged}"> 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <Label Content="{Binding Label}" /> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 
     </ListBox> 
    </Grid> 
</UserControl> 

マイコード:

using System.Collections; 
using System.Windows; 
using System.Windows.Controls; 

namespace ApplicationStyling.Controls 
{ 
    /// <summary> 
    /// Interaction logic for AutoCompleteTextBox.xaml 
    /// </summary> 
    public partial class AutoCompleteTextBox : UserControl 
    { 

     public static readonly DependencyProperty SuggestionsSourceProperty; 
     public static readonly DependencyProperty TextProperty; 

     // Events 
     public static readonly RoutedEvent TextChangedProperty; 
     public static readonly RoutedEvent SelectionChangedProperty; 


     static AutoCompleteTextBox() 
     { 
      // Attributes 
      AutoCompleteTextBox.SuggestionsSourceProperty = DependencyProperty.Register("SuggestionsSource", typeof(IEnumerable), typeof(AutoCompleteTextBox)); 
      AutoCompleteTextBox.TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(AutoCompleteTextBox)); 

      // Events 
      AutoCompleteTextBox.TextChangedProperty = EventManager.RegisterRoutedEvent("TextChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(AutoCompleteTextBox)); 
      AutoCompleteTextBox.SelectionChangedProperty = EventManager.RegisterRoutedEvent("SelectionChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(AutoCompleteTextBox)); 

     } 

     #region Events 
     public event RoutedEventHandler TextChanged 
     { 
      add { AddHandler(TextChangedProperty, value); } 
      remove { RemoveHandler(TextChangedProperty, value); } 
     } 

     // This method raises the Tap event 
     void RaiseTextChangedEvent() 
     { 
      RoutedEventArgs newEventArgs = new RoutedEventArgs(AutoCompleteTextBox.TextChangedProperty); 
      RaiseEvent(newEventArgs); 
     } 



     public event RoutedEventHandler SelectionChanged 
     { 
      add { AddHandler(SelectionChangedProperty, value); } 
      remove { RemoveHandler(SelectionChangedProperty, value); } 
     } 

     // This method raises the Tap event 
     void RaiseSelectionChangedEvent() 
     { 
      RoutedEventArgs newEventArgs = new RoutedEventArgs(AutoCompleteTextBox.SelectionChangedProperty); 
      RaiseEvent(newEventArgs); 
     } 

     #endregion 

     #region DProperties 
     /// <summary> 
     /// IEnumerable ItemsSource Property for the Suggenstion Box 
     /// </summary> 
     public IEnumerable SuggestionsSource 
     { 
      get 
      { 
       return (IEnumerable)GetValue(AutoCompleteTextBox.SuggestionsSourceProperty); 
      } 
      set 
      { 
       SetValue(AutoCompleteTextBox.SuggestionsSourceProperty, value); 
      } 
     } 

     /// <summary> 
     /// This is the Text attribute which routes to the Textbox 
     /// </summary> 
     public string Text 
     { 
      get 
      { 
       return (string)GetValue(AutoCompleteTextBox.TextProperty); 
      } 
      set 
      { 
       SetValue(AutoCompleteTextBox.TextProperty, value); 
      } 
     } 
     #endregion 

     public AutoCompleteTextBox() 
     { 
      InitializeComponent(); 
      SearchBox.TextChanged += (sender, args) => RaiseTextChangedEvent(); 
      SuggestionList.SelectionChanged += (sender, args) => RaiseSelectionChangedEvent(); 
     } 


    } 
} 

そして最後に、私はそれを使用する方法:

ascは、外部委託クラスの名前空間である
<asc:AutoCompleteTextBox x:Name="ShareAutoCompleteBox" 
           Grid.Row="3" 
           SelectionChanged="ShareAutoCompleteBox_SelectionChanged" 
           TextChanged="ShareAutoCompleteBox_TextChanged"/> 

app.xaml経由で読み込まれるライブラリ。

とにかく、私はTextBox.TextChanged属性にXAMLになって、コードを実行するときにしています問題:

はSystem.InvalidCastExceptionの:型のオブジェクトをキャストすることができません「System.Reflection.RuntimeEventInfo」と入力します'System.Reflection.MethodInfo'。

ここでは正確に何が起こっていますか? AutoCompleteTextBox TextChangedをカスタムコントロールテンプレート内のTextBoxに転送したいと思います。 ListboxSelectionChangedと同じです。

ほとんどのコードは、https://msdn.microsoft.com/en-us/library/ms752288(v=vs.100).aspx(イベントの場合)とその他のSO質問の場合はカスタムプロパティのコードのいずれかから取得しました。

わかりません。何が問題なのですか、私はあなたのお手伝いを楽しみにしています。

答えて

0

TextChangedフィールドの値をメソッド参照が必要な属性にバインドしようとしているため、例外が発生しています。それはです。実際にははWPFに混乱しています。あなたはすでに十分です、あなたのコンストラクタ内のイベントに加入

TextChanged="{Binding ElementName=AutoCompleteBox, Path=TextChanged}" 

::)

はちょうどあなたのXAMLでTextBox要素からTextChanged属性を削除します。 TextChanged属性をコンストラクタにサブスクライブするの代わりに使用する場合は、それを行うことができますが、実際のイベントハンドラを提供する必要があります。コードビハインドのメソッド。このメソッドは、現在のイベントハンドラと同様に、RaiseTextChangedEvent()メソッドを呼び出すだけです。それは、コンストラクタで宣言された匿名メソッドではなく、クラス内の名前付きメソッドであるということだけです。

他のイベントにも同じことが当てはまります。


つまり、転送されたイベントの実装を再考するかもしれません。通常、コントロールのTextプロパティは、バインドされたプロパティが変更されたときに適切に反応するモデルオブジェクトのプロパティにバインドされます。 UserControlオブジェクトでは、その値が変更されたことを伝えるために別個のイベントは必要ありません。

関連する問題