14

新しいカスタム コントロールを作成したいと考えています。これを達成する方法の手がかりを与えてくれるチュートリアルはほとんど見つかりませんでした。私が理解しているように、新しいカスタムコントロールの作成は常に現在のコントロールを拡張することによって行われ、階層の非常に基本的なレベルからコントロールを拡張することさえ可能です。たとえば、次のように拡張することもできます:

  • UIElement
  • FrameworkElement
  • コントロール
  • コンテンツ コントロール
  • HeaderedContentControl
  • アイテムコントロール
  • セレクタ
  • RangeBase

次のチュートリアルに書かれているとおり: http://wpftutorial.net/HowToCreateACustomControl.html

そこで、チュートリアルに従ってカスタム コントロール ライブラリ タイプの新しいプロジェクトを作成し、汎用の .xaml とコード ビハインドを取得しました。ここまでは順調ですね。

私が区別できるイベントには 3 つのタイプまたはカテゴリがあります。

  1. コントロールを使用するウィンドウ (またはコンテナー) によって消費されるイベント: これらは、外部に公開したいイベントです。それらをどのように書くのですか?

  2. コントロール自体に関連し、外部に公開されていないイベント。たとえば、マウスが自分のコントロールの上にあり、それに反応したい場合などです。XAML でそれを行うことができます。

    <ControlTemplate.Triggers>
      <Trigger Property="IsMouseOver" Value="true">  
        <Setter Property="Fill" TargetName="LeftTraingularIndicator">  
          <Setter.Value>  
            <SolidColorBrush Color="Yellow" />  
          </Setter.Value>  
        </Setter>
      </Trigger>
    </ControlTemplate.Triggers>  
    

もちろん、ControlTemplate に x:name="LeftTraingularIndicator" という名前の fill プロパティを持つ要素があると仮定します。

質問:

ここで、XAML で IsMouseDown に反応したいと考えています。それ、どうやったら出来るの?「IsMouseDown」トリガーはありません。さらに、コードビハインドでそれに反応したい場合はどうすればよいですか? さらに、コード ビハインドから LeftTraingularIndicator "Fill" を変更したい場合はどうすればよいでしょうか?

  1. ControlTemplate の視覚的な構成の一部であるサブ要素に関連するイベント。たとえば、XAML やコード ビハインドで「LeftTraigularIndicator」の「IsMouseOver」に反応したい場合はどうすればよいでしょうか? たぶん両方。

私は今2日間試みています...物事がどのように機能するかについての理解に何かが欠けていると感じています。これらの質問を深く説明するチュートリアルは見つかりませんでした。

ここで浮かび上がった質問のそれぞれについて、数行の例を見てみたいと思います。

ありがとう。

4

2 に答える 2

12

徹底的な調査の結果...

1)イベントを外部に公開する...他のクラスから公開するのと同じように。

public delegate void myDelegate(int someValue);  
public event myDelegate myEvent;

そしてあなたのコードのどこかに:

if(myEvent!=null)
  myEvent(5);

その部分に新しいものは何もありません。

2) コード ビハインドからインスタンス コンストラクターを作成する

public MyCustomControl()
{
    MouseMove += MyCustomControl_MouseMove;
}


void MyCustomControl_MouseMove(object sender, MouseEventArgs e)
{
   //now you can react to the movement of the mouse.
   //if for example I want to address an element, let's say a rectangle:

   var ele = (Rectangle)Template.FindName("myRect",this);
   ele.Fill=myNewBrush;

   // provided that we have an element named "myRect" (x:name="myRect") in
   // the generic.xaml style->Control Template-> which corresponds to that name.

}

3) お勧めしません - カスタム コントロールではなく、ユーザー コントロールの範囲に属しているためです。カスタム コントロールは「アトム」であり、ユーザー コントロールはコントロールを結合する目的により適しています。

しかし、不可能ではありません...

var myButton = (Button)Template.FindName("myButton",this);
myButton.OnMouseMove += ....

次の点に注意してください。

  • コード ビハインドで知っておくべきことはすべて、名前を付ける必要があります。

  • xaml には、コード ビハインドが何をするかについての知識がないはずです。(例外! - 読み続けてください)

  • コード ビハインドで認識される必要がある部分は、XAML を設計するときに正しい名前を持っている必要があります。

これが、独自のカスタム コントロールを開発しようとするときに「壁」にぶつかる他の人に役立つことを心から願っています。

于 2013-02-19T12:26:28.330 に答える
8

私があなたの質問を正しく理解していれば、以下が私の説明です。

WPF イベント システムは 3 種類のイベントを提供します: 1. バブリング 2. トンネリング 3. ダイレクト

イベントが (本質的に) バブリング イベントとして定義されている場合、イベントはソースからそのコンテナーにバブリングされます。例: Grid が 2 つのボタン (Rectangle1 と Rectangle2) をホストしている場合、これらの長方形をクリックすると、Grid にバブルアップされます。トンネリングはその反対で、イベントが親から子にトンネリングします。

非常に特別なダイレクト イベントがあります。それらは、イベントをバブルアップする意味がない場合にのみ適用されます。たとえば、上記のシナリオでは、いずれかの Rectangle で MouseOver イベントをバブルアップしても意味がありません。これは、マウスが四角形に入るたびに、イベントがグリッドにバブルアップされるためです。これは、誰かが期待することです。

あなたの質問:

私のコントロールを使用するウィンドウ (またはコンテナー) によって消費されるイベント: これらは、外部に公開したいイベントです..それらをどのように記述しますか?

基本的に、バブリング イベントを記述する必要があります。以下は、ボタンにバブリング タップ イベントを書き込む msdn の例です (自分で試したことはありません)ルーティングされたイベントの例:

public static readonly RoutedEvent TapEvent = EventManager.RegisterRoutedEvent(
"Tap", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyButtonSimple));

あなたの質問:

質問: XAML で IsMouseDown に対応したいのですが、どうすればよいですか? 「IsMouseDown」トリガーはありません..さらに、コードビハインドでそれに反応したい場合はどうすればよいですか? さらに、コード ビハインドから LeftTraingularIndicator "Fill" を変更したい場合はどうすればよいでしょうか?

ところで、あなたはイベントとトリガーを混同しているようです (私はあなたがそれらを同じ意味で使っているのを見ているからです)。それらは関連していますが、同じではありません。

質問に戻ります-WPFはプロパティの変更に対するトリガーを許可します-これは本質的にあなたがフックしているものです-この場合はIsMouseOverです。しかし、欠けているのは、プロパティが ControlTemplate のターゲットであることです(これが何であるかはわかりません)。ControlTemplate のターゲットが Rectangle であることを推測しているだけです。その場合、プロパティ トリガーをフックするための「IsMouseDown」プロパティがありません。そして、それがあなたがそれを見つけることができない理由です。AttachedEvent を記述する必要があるもう 1 つのオプション (AttachedProperties と非常によく似ています)。まったく別のトピック :(

私は最善を尽くしたことを願っています:)

于 2013-02-19T17:54:22.837 に答える