Wpf-debugging

提供:Dev Guides
移動先:案内検索

WPF-デバッグ

これは、予期したとおりに動作しないコードの一部のバグまたは欠陥を識別して修正する体系的なメカニズムです。 あるサブシステムのバグを修正すると別のサブシステムにバグが作成される可能性があるため、サブシステムが密結合している複雑なアプリケーションのデバッグはそれほど簡単ではありません。

C#でのデバッグ

WPFアプリケーションでは、プログラマはC#やXAMLなどの2つの言語を扱います。 C#やC/C ++などの手続き型言語でのデバッグに精通しており、ブレークポイントの使用方法も知っている場合は、アプリケーションのC#部分を簡単にデバッグできます。

C#コードをデバッグする方法を示す簡単な例を見てみましょう。 WPFDebuggingDemo という名前の新しいWPFプロジェクトを作成します。 ツールボックスから4つのラベル、3つのテキストボックス、および1つのボタンをドラッグします。 次のXAMLコードをご覧ください。

<Window x:Class = "WPFDebuggingDemo.Window1"
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   Title = "Window1" Height = "400" Width = "604">

   <Grid>
      <TextBox Height = "23" Margin = "0,44,169,0" Name = "textBox1"
         VerticalAlignment = "Top" HorizontalAlignment = "Right" Width = "120"/>

      <TextBox Height = "23" Margin = "0,99,169,0" Name = "textBox2"
         VerticalAlignment = "Top" HorizontalAlignment = "Right" Width = "120"/>

      <TextBox HorizontalAlignment = "Right" Margin = "0,153,169,0"
         Name = "textBox3" Width = "120" Height = "23" VerticalAlignment = "Top"/>

      <Label Height = "28" Margin = "117,42,0,0" Name = "label1"
         VerticalAlignment = "Top" HorizontalAlignment = "Left" Width = "120">
         Item 1</Label>

      <Label Height = "28" HorizontalAlignment = "Left"
         Margin = "117,99,0,0" Name = "label2" VerticalAlignment = "Top" Width = "120">
         Item 2</Label>

      <Label HorizontalAlignment = "Left" Margin = "117,153,0,181"
         Name = "label3" Width = "120">Item 3</Label>

      <Button Height = "23" HorizontalAlignment = "Right" Margin = "0,0,214,127"
         Name = "button1" VerticalAlignment = "Bottom" Width = "75"
         Click = "button1_Click">Total</Button>

      <Label Height = "28" HorizontalAlignment = "Right"
         Margin = "0,0,169,66" Name = "label4" VerticalAlignment = "Bottom" Width = "120"/>

   </Grid>

</Window>

以下に、ボタンクリックイベントが実装されるC#コードを示します。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WPFDebuggingDemo {
  ///<summary>
     ///Interaction logic for Window1.xaml
  ///</summary>

   public partial class Window1 : Window {

      public Window1() {
         InitializeComponent();
      }

      private void button1_Click(object sender, RoutedEventArgs e) {

         if (textBox1.Text.Length > 0 && textBox2.Text.Length &gt 0 && textBox2.Text.Length > 0) {
            double total = Convert.ToDouble(textBox1.Text) +
            Convert.ToDouble(textBox2.Text) + Convert.ToDouble(textBox3.Text);
            label4.Content = total.ToString();
         }
         else {
            MessageBox.Show("Enter the value in all field.");
         }
      }
   }
}

上記のコードをコンパイルして実行すると、次のウィンドウが生成されます。 ここで、テキストボックスに値を入力し、[合計]ボタンを押します。 テキストボックスに入力されたすべての値の合計後に合計値を取得します。

デバッグ

実際の値以外の値を入力しようとすると、上記のアプリケーションがクラッシュします。 問題を見つけて解決するには(クラッシュする理由)、ボタンクリックイベントにブレークポイントを挿入できます。

以下に示すように、アイテム1に「abc」と書きましょう。

アイテム1

[合計]ボタンをクリックすると、プログラムがブレークポイントで停止することがわかります。

プログラムがクラッシュしています

次に、カーソルをtextbox1.Textの方向に移動すると、プログラムが abc 値を他の値に追加しようとしていることがわかります。これが、プログラムがクラッシュする理由です。

XAMLでのデバッグ

XAMLで同じ種類のデバッグを期待している場合、他の手続き言語コードのデバッグのようにXAMLコードをまだデバッグできないことを知って驚くでしょう。 XAMLコードでデバッグという言葉を聞いたとき、それはエラーを見つけて見つけることを意味します。

  • データバインディングでは、データは画面に表示されず、理由もわかりません
  • または、問題は複雑なレイアウトに関連しています。
  • または、位置合わせの問題または余白の色、オーバーレイなどの問題 ListBoxやコンボボックスなどの広範なテンプレートを使用します。

XAMLプログラムのデバッグは、通常、バインディングが機能するかどうかを確認するために行います。そして、それが機能していない場合、何が悪いのかをチェックします。 残念ながら、Silverlight以外ではXAMLバインディングにブレークポイントを設定することはできませんが、出力ウィンドウを使用してデータバインディングエラーをチェックすることはできます。 次のXAMLコードを見て、データバインディングのエラーを見つけましょう。

<Window x:Class = "DataBindingOneWay.MainWindow"
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   Title = "MainWindow" Height = "350" Width = "604">

   <Grid>
      <StackPanel Name = "Display">
         <StackPanel Orientation = "Horizontal" Margin = "50, 50, 0, 0">
            <TextBlock Text = "Name: " Margin = "10" Width = "100"/>
            <TextBlock Margin = "10" Width = "100" Text = "{Binding FirstName}"/>
         </StackPanel>

         <StackPanel Orientation = "Horizontal" Margin = "50,0,50,0">
            <TextBlock Text = "Title: " Margin = "10" Width = "100"/>
            <TextBlock Margin = "10" Width = "100" Text = "{Binding Title}"/>
         </StackPanel>

      </StackPanel>
   </Grid>

</Window>

2つのテキストブロックのテキストプロパティは「Name」と「Title」に静的に設定され、他の2つのテキストブロックのテキストプロパティは「FirstName」と「Title」にバインドされますが、クラス変数は以下に示すEmployeeクラスのNameとTitleです。

目的の出力が表示されない場合、このタイプの間違いをどこで見つけることができるかを理解するために、意図的に誤った変数名を記述しました。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DataBindingOneWay {

   public class Employee {
      public string Name { get; set; }
      public string Title { get; set; }

      public static Employee GetEmployee() {

         var emp = new Employee() {
            Name = "Ali Ahmed", Title = "Developer"
         };

         return emp;
      }
   }
}

C#コードでのMainWindowクラスの実装を次に示します。

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

namespace DataBindingOneWay {
  ///<summary>
     ///Interaction logic for MainWindow.xaml
  ///</summary>

   public partial class MainWindow : Window {

      public MainWindow() {
         InitializeComponent();
         DataContext = Employee.GetEmployee();
      }
   }
}

このアプリケーションを実行してみましょう。MainWindowで、EmployeeオブジェクトのTitleに正常にバインドされたが、名前がバインドされていないことがすぐにわかります。

XAMLでのデバッグ

名前で何が起こったのかを確認するために、大量のログが生成される出力ウィンドウを見てみましょう。

エラーを見つけるのは簡単です。エラーを検索するだけで、「BindingExpression path error: 'FirstName' property not found on 'object' Employe _

System.Windows.Data Error: 40 : BindingExpression path error: 'FirstName'
   property not found on 'object' ''Employee' (HashCode=11611730)'.
   BindingExpression:Path = FirstName; DataItem = 'Employee' (HashCode = 11611730);
   target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')

FirstNameはEmployeeクラスのメンバーではないことを明確に示しているため、アプリケーションでこの種の問題を解決するのに役立ちます。

FirstNameを再度Nameに変更すると、目的の出力が表示されます。

XAMLのUIデバッグツール

実行時にXAMLコードを検査するために、Visual Studio 2015でXAMLにUIデバッグツールが導入されました。 これらのツールを使用すると、XAMLコードは実行中のWPFアプリケーションの視覚的なツリーの形式で表示され、ツリー内のさまざまなUI要素プロパティも表示されます。 これらのツールを有効にするには、以下の手順に従ってください。

  • [ツール]メニューに移動し、[ツール]メニューから[オプション]を選択します。
  • 次のダイアログボックスが開きます。

デバッグツール

  • 左側の「デバッグ」項目の下の「一般オプション」に移動します。
  • 強調表示されたオプション、つまり「XAMLのUIデバッグツールを有効にする」にチェックマークを付け、[OK]ボタンをクリックします。

XAMLアプリケーションを実行するか、次のXAMLコードを使用します。

<Window x:Class = "XAMLTestBinding.MainWindow"
   xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
   Title = "MainWindow" Height = "350" Width = "604">

   <StackPanel>
      <ComboBox Name = "comboBox"  Margin = "50" Width = "100">
         <ComboBoxItem Content = "Green"/>
         <ComboBoxItem  Content = "Yellow" IsSelected = "True"/>
         <ComboBoxItem Content = "Orange"/>
      </ComboBox>

      <TextBox  Name = "textBox" Margin = "50" Width = "100" Height = "23"
         VerticalAlignment = "Top" Text  =
         "{Binding ElementName = comboBox, Path = SelectedItem.Content, Mode = TwoWay, UpdateSourceTrigger = PropertyChanged}"
         Background = "{Binding ElementName = comboBox, Path = SelectedItem.Content}">
      </TextBox>

   </StackPanel>

</Window>

アプリケーションを実行すると、すべての要素がツリーで表示されるライブビジュアルツリーが表示されます。

ライブビジュアルツリー

このライブビジュアルツリーは、UI要素の場所を理解するための完全なレイアウト構造を示しています。 ただし、このオプションはVisual Studio 2015でのみ使用可能です。 Visual Studioの古いオプションを使用している場合、このツールは使用できませんが、XAML Spy for Visual Studioなど、Visual Studioと統合できる別のツールがあります。 xamlspyからダウンロードできます。