VBプログラマの為のWPF入門

VB Tips And Sample(HOME)VBプログラマの為のWPF入門

VBプログラマの為のWPF入門

そろそろWPFをやっておこう。
と言うわけで、VB2010Expressのツールボックスの上のコントロールから順番にフォームコピペしてサンプルを動かしてみよう!
最初は、Borderコントロールなのだが、今はそんなに難しくなさそう。とりあえず使ってみた感じ、今の所、プロパティーボックスの設定で事足りるようだ。
次に、Buttonコントロール。これも、今の所、プロパティーボックスの設定で事足りるようだ。
CheckBoxコントロール。これも、今の所、プロパティーボックスの設定で事足りるようだ。
ComboBoxコントロール。なにやら変わっているので調べてみよう。
と言うわけで初回は、ComboBoxコントロール。
(どこぞのサイトで、ユーザ登録するとサンプルが見られるようなページがあるようだが、どうなんでしょ?)

XAMLを整形するには?

XAMLを直接各WPFプログラムですが、書いていると、インデントを整えたくなります。
XAMLの画面にカーソルを入れて、「Ctrl + K」 、「Ctrl + D」のショートカットキーで整えてくれます。
実際には、「Ctrlを押した状態で、Kをタイプ、次にCtrlを押したまま、Dをタイプします。」

ComboBox


今回作ってみたのは、
コンボボックス
といういかにもサンプル的な、サンプル。
XMLをMSが改造してXAML(ザムル)なるものを作ったのだが、要はXMLだ。
しかし、言っては何だが、ツールボックスからドラッグドロップすると、XAMLのコードがグチャグチャになるので、まだXAMLのいい所を感じない。管理人だけ?
結局、後はXAMLを直接書くしかなくなるという、VBらしさが結構消えている所が問題かも?

ま、愚痴は置いといて、ComboBoXをみてみよう。
太い青色の箇所はXAMLに直接アイテムを書いてみたら追加できてきちんと動くことが確認できた。
なんだか、HTMLみたいだがそのとおりみたいだ。
もちろん、VB側でもアイテムは追加可能だ。チーム開発では、どっちでするか統一しておいた方がいいかもしれない。

XAML
	<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="348" Width="456" WindowStartupLocation="CenterScreen" >
    <Grid Width="472"> 最初からグリッドになっている。よーするに、こいつが標準と言うわけらしい。
        <Grid.Resources>

            <!--TargetTypeを指定すると、個々の記述は不要-->
            <Style TargetType="ComboBox">
                <Setter Property="Margin" Value="40,10,0,0" />
            </Style>
            <!--名前月スタイルでコントロールのマージンを一括設定。しかし個々のコントロールに記述する必要あり。TargetTypeより優先される-->
            <Style x:Key="thisPG_Margin">
                <Setter Property="Control.Margin" Value="20,10,0,0" />
            </Style>
        </Grid.Resources>
        <Border BorderBrush="#FFC05C1A" BorderThickness="1" Height="Auto" HorizontalAlignment="Left" Margin="23,38,0,0" Name="Border1" VerticalAlignment="Top" Width="Auto" Background="#699D303A" CornerRadius="10">
            <Grid Height="249" Width="401">
                <Grid.RowDefinitions>
                    <RowDefinition Height="*" />
                    <RowDefinition Height="*" />
                    <RowDefinition Height="*" />
                    <RowDefinition Height="*" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>

                <Label Grid.Row="0" Content="Borderコントロール" Height="28" HorizontalAlignment="Left" Name="Label1" VerticalAlignment="Top" Style="{StaticResource thisPG_Margin}" />
                <Button Grid.Row="1" Content="都道府県取得" Height="39" HorizontalAlignment="Left" Name="Button1" VerticalAlignment="Top" Width="121" Style="{StaticResource thisPG_Margin}" />
                <CheckBox Content="CheckBox" Grid.Row="2" Height="16" HorizontalAlignment="Left" Name="CheckBox1" VerticalAlignment="Top" Style="{StaticResource thisPG_Margin}" />
                <Label Content="経過時間" Grid.Column="1" Grid.Row="2" Height="28" Name="Label2" />
                <ComboBox Grid.Row="3" Height="24" HorizontalAlignment="Left"  Name="ComboBox1" VerticalAlignment="Top" Width="120" Style="{StaticResource thisPG_Margin}" >
                    <ComboBoxItem Content="北海道" IsSelected="True" />
                    <ComboBoxItem Content="青森" />
                    <ComboBoxItem Content="秋田" />
                    <ComboBoxItem Content="岩手" />
                </ComboBox>

                <Image Grid.Row="4" Height="24" HorizontalAlignment="Left" Name="Image1" Stretch="Fill" VerticalAlignment="Top" Width="168" Style="{StaticResource thisPG_Margin}" Margin="20,10,0,0" />
                <ComboBox Grid.Row="3" Grid.Column="1" Height="24" HorizontalAlignment="Left" Name="ComboBox2" VerticalAlignment="Top" Width="120" Style="{StaticResource thisPG_Margin}" />
                <ComboBox Grid.Column="1" Grid.Row="4" Height="24" HorizontalAlignment="Left" Name="ComboBox3" VerticalAlignment="Top" Width="120" />
                <Button Content="都道府県検索2" Grid.Column="1" Grid.Row="1" Name="Button2" Width="155" Margin="23,10,23,9" />
            </Grid>
            
        </Border>
    </Grid>
	</Window>
	
	


次が、Me.ComboBox2.ItemsSourceに、SQLServer2008Expressから取得したデータのビュー(見方)を代入している所。
データは、いつもの郵便局データ。
SQLサーバへの接続等は以前のサンプルもあるので、データビューのソート機能等を使ってみる。
結果は、えらく遅いので、できるだけSQLで処理したほうがよさそうです。
この処理で1秒ぐらいかかった。
ボトルネックは、データビューの非重複処理の箇所で、コストが大きい。因みに、SELECT DISTINCTで絞ると、データ取得時間はほぼ0秒だった。
餅は餅屋ですか。


Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
        'SQLサーバからKEN_ALLを検索取得
        'データテーブルで被重複名ビューを取得

        Dim DA As New SqlDataAdapter
        Dim cnn As New SqlConnection
        Dim cmnd As New SqlCommand
        Dim ds As DataSet = New DataSet


        Try
            'すべてのテーブル内のすべての行を削除して、データの DataSet を消去します。
            ds.Clear()

            'コネクションストリングを設定
            cnn.ConnectionString = "user id=vbuser;password=sa;initial catalog=MYTEST;data source=(local);Connect Timeout=5"
            'cnn.ConnectionString = "user id=vbuser;password=sa;initial catalog=MYTEST;data source=PC名\SQLEXPRESS;Connect Timeout=5"
            'この接続は明示的にオープンクローズする必要がない。Fillでオープンクローズを勝手にしてくれる

            'http://msdn.microsoft.com/ja-jp/library/system.diagnostics.stopwatch(VS.80).aspx
            Dim i As New System.Diagnostics.Stopwatch()

            i.Start()

            'SQL文を設定し、コマンドにコネクションを設定する
            Dim MySQL As String
            'わざと並びを変えて
            MySQL = "SELECT LEFT(県コード,2) AS コード,県 FROM KEN_ALL ORDER BY 県"
            cmnd.CommandText = MySQL
            cmnd.Connection = cnn

            'データアダプターにコマンドを設定
            DA.SelectCommand = cmnd

            'レコード数の取得
            Dim reCount As Integer

            'データセットにデータの実態を取得する()
            reCount = DA.Fill(ds, "KEN_ALL")

            'MessageBox.Show(reCount)

            Dim tbv As New DataView
            tbv.Table = ds.Tables("KEN_ALL")

            'データビューで非重複(ToTable)にするだけで約1秒かかってしまう。
            'できるだけSQLで処理すべきみたいだ。
            Dim strfields() As String = {"コード", "県"}

            Me.ComboBox2.ItemsSource = tbv.ToTable(True, strfields).DefaultView
            Me.ComboBox2.DisplayMemberPath = "県"
            Me.ComboBox2.SelectedValuePath = "コード"
            Me.ComboBox2.SelectedIndex = 0

            '並びを変えた場合
            tbv.Sort = "コード"
            Me.ComboBox3.ItemsSource = tbv.ToTable(True, strfields).DefaultView
            Me.ComboBox3.DisplayMemberPath = "県"
            Me.ComboBox3.SelectedValuePath = "コード"
            Me.ComboBox3.SelectedIndex = 0

            i.Stop()

            Label2.Content = i.Elapsed
        Catch ex As Exception
            MessageBox.Show(ex.Message, "SQL検索", MessageBoxButton.OK, MessageBoxImage.Error)
        End Try

    End Sub


で、これではいかにも芸が無いので、
VBで以前、ComboBoxに画像を追加した時のように、画像を入れてみたのが、次のサンプル。
画像つきコンボ
方法は、XAMLで、
	 <ComboBox Grid.Row="3" Height="24" HorizontalAlignment="Left"  Name="ComboBox1" VerticalAlignment="Top" Width="120" Style="{StaticResource thisPG_Margin}" >
                    <ComboBoxItem IsSelected="True">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <Label Grid.Column="0" Content="北海道" />
                            <Image Grid.Column="1" Name="Image2" Stretch="Fill" VerticalAlignment="Top" Source="/WpfApplicationTips;component/Images/o0640048011914843315.jpg" />
                        </Grid>
                    </ComboBoxItem>
                    <ComboBoxItem Content="青森" />
                    <ComboBoxItem Content="秋田" />
                    <ComboBoxItem Content="岩手" />
                </ComboBox>
	
	

赤い箇所を書き換えただけ。
これを、VB側で動的に操作するとなると、バインドという手法を使うようになるのだろうか?
またそれは、いつかの折に・・・・
しかし、こういったことが簡単になったと言えばなったと言える。


VB Tips And Sample(HOME)VBプログラマの為のWPF入門