none
ButtonのNameプロパティを、プロパティ要素構文で記載すると、Clickイベントが発生しない RRS feed

  • 質問

  • 以下のように、2つのButtonのName属性をプロパティ要素構文で記載した場合、
    2つ目のボタンをクリックしても、Clickイベントが発生しません。
    また、1つ目のボタンをクリックすると、Clickイベントが2回発生します。

    <WrapPanel>
        <Button Click="Button_Click">
            <Button.Name>Button1</Button.Name>
            <Button.Content>Button1</Button.Content>
        </Button>
        <Button Click="Button_Click">
            <Button.Name>Button2</Button.Name>
            <Button.Content>Button2</Button.Content>
        </Button>
     </WrapPanel>

    XAMLの書き方に問題があるのでしょうか?

    因みにName属性を、要素構文で記載すると、正しく動作します。
    2009年7月16日 3:20

回答

  • obj\windows1.g.cs を見てみました。
            #line 8 "..\..\Window1.xaml"
            internal System.Windows.Controls.Button Button1;
            
            #line default
            #line hidden
            
            
            #line 12 "..\..\Window1.xaml"
            internal System.Windows.Controls.Button Button2;
            
            #line default
            #line hidden
    ボタンの作成はこんな感じです。
            void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
                switch (connectionId)
                {
                case 1:
                
                #line 7 "..\..\Window1.xaml"
                ((System.Windows.Controls.Button)(target)).Click += new System.Windows.RoutedEventHandler(this.Button_Click);
                
                #line default
                #line hidden
                return;
                case 2:
                this.Button1 = ((System.Windows.Controls.Button)(target));
                
                #line 11 "..\..\Window1.xaml"
                this.Button1.Click += new System.Windows.RoutedEventHandler(this.Button_Click);
                
                #line default
                #line hidden
                return;
                }
                this._contentLoaded = true;
            }
    

    Line7 8 が Button1
    Line11 12 が Button2 のはずですがおかしいですね。

    このページには「XAML x:Name 属性を設定するための WPF フレームワーク レベルの便利なプロパティ」とありますのでプロパティ要素構文を前提としていないのかもしれません。
    http://msdn.microsoft.com/ja-jp/library/system.windows.frameworkelement.name(VS.80).aspx

    バグとも言えそうですが、By desiign で返されそうな気もします。
    えムナウ@わんくま同盟 Microsoft MVP Visual Studio C# Since 2005/01-2009/12
    • 回答としてマーク 遊戯三昧 2009年7月26日 20:40
    2009年7月19日 1:56
  • 以下のコードのように Button2 は x:Name で設定して

    <WrapPanel>
        <Button>
            <Button.Name>Button1</Button.Name> // <---何か悪さをしている
        <Button.Content>Button1</Button.Content>
        </Button>
        <Button x:Name="Button2" Click="Button_Click">
            <Button.Content>Button2</Button.Content>
        </Button>
    </WrapPanel>

    XAMLコンパイル後の .g.cs 系 のコードを見ると,
    以下のようにハンドラの登録は Button2 にされているのに,
      
        this.Button2.Click += new System.Windows.RoutedEventHandler(this.Button_Click);

    なぜか Button1 の Clickイベントに対して Button_Clickハンドラが反応 してしまうので

         <Button.Name>Button1</Button.Name>

    の地点で具合が悪いようですね。

    このプロパティ要素を使う形での指定を想定していないように見えるので,
    いわゆる,仕様でよく出てくる
    the results are unpredictable 状態じゃないですかね。

    XAMLの仕様では,x:Nameディレクティブ と
    それを オブジェクトの名前と関連付ける仕組みを用意しているだけで,
    どう処理するかは実装側にまかせてます。

    XAMLプロセッサのMS実装が,
    プロパティ要素を使う形での指定を想定しているのかは,わかりませんが,
    上のコードを見る限りは,
    想定していないように見えます。
    ヘルプには,
    uncommon という表記があるぐらいですが...。

    • 編集済み yayadon 2009年7月21日 11:42 レイアウト修正
    • 回答としてマーク 遊戯三昧 2009年7月26日 20:40
    2009年7月20日 14:44

すべての返信

  • うちでも再現しました。
    デバッガで様子を見てみると、Button2は、コードビハインドから見るとnullが
    入っていました。

    何がおきてるんでしょうね・・・。


    かずき Blog:http://blogs.wankuma.com/kazuki/
    2009年7月16日 10:50
  • obj\windows1.g.cs を見てみました。
            #line 8 "..\..\Window1.xaml"
            internal System.Windows.Controls.Button Button1;
            
            #line default
            #line hidden
            
            
            #line 12 "..\..\Window1.xaml"
            internal System.Windows.Controls.Button Button2;
            
            #line default
            #line hidden
    ボタンの作成はこんな感じです。
            void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
                switch (connectionId)
                {
                case 1:
                
                #line 7 "..\..\Window1.xaml"
                ((System.Windows.Controls.Button)(target)).Click += new System.Windows.RoutedEventHandler(this.Button_Click);
                
                #line default
                #line hidden
                return;
                case 2:
                this.Button1 = ((System.Windows.Controls.Button)(target));
                
                #line 11 "..\..\Window1.xaml"
                this.Button1.Click += new System.Windows.RoutedEventHandler(this.Button_Click);
                
                #line default
                #line hidden
                return;
                }
                this._contentLoaded = true;
            }
    

    Line7 8 が Button1
    Line11 12 が Button2 のはずですがおかしいですね。

    このページには「XAML x:Name 属性を設定するための WPF フレームワーク レベルの便利なプロパティ」とありますのでプロパティ要素構文を前提としていないのかもしれません。
    http://msdn.microsoft.com/ja-jp/library/system.windows.frameworkelement.name(VS.80).aspx

    バグとも言えそうですが、By desiign で返されそうな気もします。
    えムナウ@わんくま同盟 Microsoft MVP Visual Studio C# Since 2005/01-2009/12
    • 回答としてマーク 遊戯三昧 2009年7月26日 20:40
    2009年7月19日 1:56
  • 以下のコードのように Button2 は x:Name で設定して

    <WrapPanel>
        <Button>
            <Button.Name>Button1</Button.Name> // <---何か悪さをしている
        <Button.Content>Button1</Button.Content>
        </Button>
        <Button x:Name="Button2" Click="Button_Click">
            <Button.Content>Button2</Button.Content>
        </Button>
    </WrapPanel>

    XAMLコンパイル後の .g.cs 系 のコードを見ると,
    以下のようにハンドラの登録は Button2 にされているのに,
      
        this.Button2.Click += new System.Windows.RoutedEventHandler(this.Button_Click);

    なぜか Button1 の Clickイベントに対して Button_Clickハンドラが反応 してしまうので

         <Button.Name>Button1</Button.Name>

    の地点で具合が悪いようですね。

    このプロパティ要素を使う形での指定を想定していないように見えるので,
    いわゆる,仕様でよく出てくる
    the results are unpredictable 状態じゃないですかね。

    XAMLの仕様では,x:Nameディレクティブ と
    それを オブジェクトの名前と関連付ける仕組みを用意しているだけで,
    どう処理するかは実装側にまかせてます。

    XAMLプロセッサのMS実装が,
    プロパティ要素を使う形での指定を想定しているのかは,わかりませんが,
    上のコードを見る限りは,
    想定していないように見えます。
    ヘルプには,
    uncommon という表記があるぐらいですが...。

    • 編集済み yayadon 2009年7月21日 11:42 レイアウト修正
    • 回答としてマーク 遊戯三昧 2009年7月26日 20:40
    2009年7月20日 14:44
  • 調査、検討、ありがとうございます。

    MSの仕様と思って、理解しておきます。
    2009年7月26日 20:52