2013年07月30日

WPFサンプル: AutoReverseとRepeatBehaviorでアニメーションを繰り返す

   このエントリーをはてなブックマークに追加 Clip to Evernote
今回は、DoubleAnimationのAutoReverseとRepeatBehaviorプロパティを使った例です。 この2つのプロパティで、アニメーションの繰り返しについて指定できます(後述)。

なお、「DoubleAnimationを使ったアニメーション」では、Button_Clickイベントハンドラで、アニメーションを開始させましたが、今度は、イベントトリガーを使い、アニメーションを開始します。
イベントトリガーを使いイベントとStoryboardを結びつけることで、C#のコードを書かなくても、アニメーションを開始することができます。

XAMLです。

<Window x:Class="AutoReverseSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Storyboard x:Key="myStoryboard"  FillBehavior="HoldEnd">
            <DoubleAnimation
                    Storyboard.TargetName="image1"
                    Storyboard.TargetProperty="Opacity"
                    From="1" To="0" Duration="0:0:04"
                    AutoReverse="True" RepeatBehavior="2x" />
        </Storyboard>
    </Window.Resources>
    <Grid x:Name="LayoutRoot" Background="White">
        <Button Content="Start" Height="23" HorizontalAlignment="Left" Margin="10,7,0,0"
                    Name="button1" VerticalAlignment="Top" Width="75"  >
            <Button.Triggers>
                <EventTrigger RoutedEvent="Button.Click">
                    <BeginStoryboard Storyboard="{Binding Source={StaticResource myStoryboard}}" />
                </EventTrigger>
            </Button.Triggers>
        </Button>

        <Image Height="138" HorizontalAlignment="Left" Margin="8,37,0,0" Name="image1"
               Stretch="Fill" VerticalAlignment="Top" Width="180"
               Source="/Images/Desert.jpg" Opacity="1"/>
    </Grid>
</Window>

Button.Clickイベントで、Storyboardを呼び出すようにしています。
Clickイベント以外のイベントでもアニメーションを開始することができます。Loadedイベントを使えば、ウィンドウが開いたときにアニメーションを開始できます。

さて、本題のAutoReverse プロパティと、RepeatBehaviorプロパティですが、 AutoReverseをtrueとすることで、プロパティの値が、To の値まで変化した後に、今度は To値から Fromの値に変化します。
RepeatBehaviorは、再生回数または再生時間の合計を指定できます、ここでは、2x とすることで、2回繰り返してアニメーションを再生させています。Foreverを指定すると無限に繰り返します。
AutoReverseをfalse(規定値)の場合は、プロパティの値が、Toまで変化したら、再度、Fromの値に戻りアニメーションが繰り返されます。

この例では、Opacityプロパティの値を変化させています。

以下、実行時のスクリーンショットです。

AutoReverse1

AutoReverse2

AutoReverse3


WPFサンプル・目次
  

Posted by gushwell at 23:00Comments(0)TrackBack(0)

2013年07月28日

WPFサンプル:DoubleAnimationを使ったアニメーション

   このエントリーをはてなブックマークに追加 Clip to Evernote
今日から、数回に分けてWPFのアニメーション機能のサンプルを掲載していきます。

WPFのアニメーションは、各オブジェクトのプロパティの値を指定した期間の間で変化させることでアニメーションを実現させています。
例えば、あるコントロールのWidthを小さい値から大きい値へ変化させれば、コントロールが徐々幅広になるアニメーションを実現できます。

今回は、Double型のプロパティ値を変化させることができる DoubleAnimationのサンプルをお見せします。

では、まずはXAMLから。

<Window x:Class="DoubleAnimationSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Storyboard x:Key="MyAnimation" FillBehavior="HoldEnd">
            <DoubleAnimation From="0" To="60" Duration="00:00:00.50"
                             Storyboard.TargetName="textBlock"
                             Storyboard.TargetProperty="FontSize" />
        </Storyboard>
    </Window.Resources>
    <StackPanel x:Name="LayoutRoot" Background="White">
        <Button Content="Button" Height="26" HorizontalAlignment="Left"
                Margin="12,12,0,0" Name="button1" VerticalAlignment="Top"
                Width="75" Click="button1_Click" />
        <Button Click="Button_Click" Width="75" Content="開始" HorizontalAlignment="Left"/>
        <TextBlock Text="DoubleAnimation" FontSize="1" Name="textBlock" />
    </StackPanel>
</Window>

アニメーションをオブジェクトに適用するには、Storyboard を作成する必要があります。
Storyboardの子要素として、DoubleAnimationを定義しています。
そして、TargetName および TargetProperty 添付プロパティを使用してアニメーション化する オブジェクトとプロパティを指定します。
From, Toプロパティは、TargetPropertyの値をどこからどこまで変化させるのか、Durationでその時間を指定します。

この例では、TextBlockのFontSizeプロパティを 0.5秒の間で 0 から 60 まで変化させています。

ボタンがクリックされるとアニメーションが開始されますが、それは、C#のコードで実装しています。

using System;
using System.Windows;
using System.Windows.Media.Animation;

namespace DoubleAnimationSample {
    public partial class MainWindow : Window {
        public MainWindow() {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e) {
            (this.Resources["MyAnimation"] as Storyboard).Begin();
        }
    }
}

Storyboard.Begin メソッドで、アニメーションが開始させれます。
以下実行結果のスクリーンショットです。

doubleAnimation1

doubleAnimation2

doubleAnimation3


なお、XAMLを使わずに、Storyboardオブジェクトの生成とアニメーションの開始をC#側で記述すると以下のようになります。

XAMLの記述とC#のコード対応しているのがわかると思います。

using System;
using System.Windows;
using System.Windows.Media.Animation;

namespace DoubleAnimationSample {
    public partial class MainWindow : Window {
        public MainWindow() {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e) {
            DoubleAnimation myDoubleAnimation = new DoubleAnimation();
            myDoubleAnimation.From = 0.0;
            myDoubleAnimation.To =  50.0;
            myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(0.5));
            Storyboard.SetTargetProperty(myDoubleAnimation,new PropertyPath("FontSize"));
            Storyboard.SetTarget(myDoubleAnimation, this.textBlock);
            var myStoryboard = new Storyboard();
            myStoryboard.FillBehavior = FillBehavior.HoldEnd;
            myStoryboard.Children.Add(myDoubleAnimation);
            myStoryboard.Begin();

        }
    }
}


WPFサンプル・目次
  
Posted by gushwell at 22:30Comments(0)TrackBack(0)

2013年07月25日

WPFサンプル:LINQクエリの結果をバインドする(2)

   このエントリーをはてなブックマークに追加 Clip to Evernote
LINQクエリの結果をバインドする(1)」では、クエリの結果を直接 ItemsSourceに代入していましたが、今回は、このシーケンスを取得するプロパティ(例えばIEnumerable<object> 型)をもつクラスを定義して、コードビハインドにコードを書かずに、XAML側でバインドしています。

例えば、以下のようなMyColorsクラスをC#で定義します。
Colorsプロパティは、readonlyプロパティで匿名クラスのシーケンスを返します。

public class MyColors {
    public IEnumerable<object> Colors {
       get {
           var colornames = from color in typeof(Colors).GetProperties()
                            select new  {
                                Name = color.Name,
                                Color = (Color)color.GetValue(null, null)
                            };
           return colornames;
       }
    }
}

LINQのクエリ式は、匿名クラスのシーケンスを返しているので、IEnumerable<object> としています。バインドするだけならば、これで問題はありません。
もちろん、

public class ColorInfo {
   public string Name { get ; set ; }
   public Color Color { get ; set ; }
}

といったクラスを定義しても構いません。

XAMLは以下のようになります。

<Window x:Class="BindingLinqSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:my="clr-namespace:BindingLinqSample"
        Title="MainWindow" Height="320" Width="220">
    <Window.Resources>
        <DataTemplate x:Key="myTemplate">
            <StackPanel Orientation="Horizontal">
                <Rectangle Width="30" Margin="2" >
                    <Rectangle.Fill>
                        <SolidColorBrush Color="{Binding Path=Color}" />
                    </Rectangle.Fill>
                </Rectangle>
                <TextBlock Text="{Binding Path=Name}" />
            </StackPanel>
        </DataTemplate>
    </Window.Resources>
    <Window.DataContext>
        <my:MyColors />
    </Window.DataContext>
    <Grid>
        <ListBox Margin="10,10,10,50" Name="listBox1" 
                 ItemTemplate="{StaticResource myTemplate}"
                 ItemsSource="{Binding Colors}"/>
        <Border Margin="15" VerticalAlignment="Bottom"
                BorderThickness="1" BorderBrush="Gray">
            <ContentControl
                ContentTemplate="{StaticResource myTemplate}"
                Content="{Binding SelectedItem, ElementName=listBox1}" />
        </Border>
    </Grid>
</Window>

DataTemplate の、{Binding Path=Color} や {Binding Path=Name} は、ColorやNameは、匿名クラスのプロパティとなっています。
こうすれば、コードビハインドにはコードを追加する必要はなくなります。

LinqBinding2

WPFサンプル・目次
  
Posted by gushwell at 22:30Comments(0)TrackBack(0)

2013年07月23日

WPFサンプル:LINQクエリの結果をバインドする(1)

   このエントリーをはてなブックマークに追加 Clip to Evernote
LINQ to Objectのクエリの結果(ここでは、匿名クラスのシーケンス)をListBoxにバインドするサンプルを示します。
以下、そのスクリーンショットです。

LinqBinding1

C# のコードはいたって簡単。
typeof(Colors).GetProperties() でColorsに定義されているプロパティ一覧を取得し、Name と Color の情報を抜出し、そのシーケンスを求めています。
このLINQクエリの結果をLIstBox.ItemsSourceにバインドしているだけです。

以下、C#のソースを示します。

using System.Linq;
using System.Windows;
using System.Windows.Media;
namespace BindingLinqSample {
    public partial class MainWindow : Window {
        public MainWindow() {
            InitializeComponent();
            var colorinfos = from color in typeof(Colors).GetProperties()
                             select new {
                                 Name = color.Name,
                                 Color = color.GetValue(null, null)
                             };
            listBox1.ItemsSource = colorinfos;
        }
    }
}

なお、XAMLでは、ListBoxの各行に実際の色と色の名前を表示するために、DataTemplateを利用しています。
今回の例では、匿名クラスには、NameとColorというプロパティが存在しますが、DatTemplateを使うことで、Nameを表示するのか、Colorを表示するのか、はたまた両方を表示するのか、そしてそれをどう表示するのかを定義することができます。
XAML側でも、匿名クラスのプロパティである Name, Colorプロパティを参照している点に注目してください。


<Window x:Class="BindingLinqSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="320" Width="240">
    <Window.Resources>
        <DataTemplate x:Key="myTemplate">
            <StackPanel Orientation="Horizontal">
                <Rectangle Width="30" Margin="2" >
                    <Rectangle.Fill>
                        <SolidColorBrush Color="{Binding Path=Color}" />
                    </Rectangle.Fill>
                </Rectangle>
                <TextBlock Text="{Binding Path=Name}" />
            </StackPanel>
        </DataTemplate>
        <DataTemplate x:Key="myTemplate2">
                <TextBlock Text="{Binding Path=Name}" />
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <ListBox Margin="15,15,15,45" Name="listBox1" 
                 ItemTemplate="{StaticResource myTemplate}" />
        <Border Margin="15" VerticalAlignment="Bottom"
                BorderThickness="1" BorderBrush="Gray">
            <ContentControl
                    ContentTemplate="{StaticResource myTemplate}"
                    Content="{Binding SelectedItem, ElementName=listBox1}" />
        </Border>
    </Grid>
</Window>


WPFサンプル・目次
  
Posted by gushwell at 22:30Comments(0)TrackBack(0)

2013年07月21日

WPFサンプル:RelativeSourceでターゲットの位置を基準にしてソースを指定する

   このエントリーをはてなブックマークに追加 Clip to Evernote
RelativeSourceマークアップ拡張を使うと、バインディング ターゲットの位置を基準にしてソースを指定することができます。

まずは一つ目のサンプル

RelativeSourceSample1 RelativeSourceSample2

これは、RelativeSource を使い、Rectangleの縦横の長さを常に同じにしている例です。
Sliderの値によって、Rectangleは、サイズが変わりますが、その時、

Height="{Binding RelativeSource={RelativeSource Self},Path=Width}"

とすることで、自分自身のWidthとバインドしています。

<Window x:Class="RelativeSourceSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        Title="MainWindow" Height="200" Width="200" >
    <Grid Background="White">
        <Slider Height="23" HorizontalAlignment="Stretch" x:Name="slider1"
                VerticalAlignment="Top" Maximum="100" Margin="10" Value="20"/>
        <Rectangle HorizontalAlignment="Stretch" x:Name="rectangle1"
             Stroke="Black" Fill="#FFD5C0B9"
             Width="{Binding Value, ElementName=slider1}"    
             Height="{Binding RelativeSource={RelativeSource Self},Path=Width}" />
    </Grid>
</Window>

もう一つのサンプル
まずは、スクリーンショットとXAMLを示します。

RelativeSourceSample3

<Window x:Class="RelativeSourceSample.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300">
    <Grid Background="White">
        <Border BorderBrush="#FFB9BCFB" BorderThickness="3" HorizontalAlignment="Left" 
                Height="120" Margin="41,30,0,0" VerticalAlignment="Top" Width="190">
            <Border.Background>
                <LinearGradientBrush EndPoint="0,0.5" MappingMode="RelativeToBoundingBox" 
                                     StartPoint="1,0.5">
                    <GradientStop Color="#FF49497A" Offset="1"/>
                    <GradientStop Color="#FFC2DEFF"/>
                </LinearGradientBrush>
            </Border.Background>
            <StackPanel Orientation="Horizontal" Margin="10">
                <Rectangle Width="30" Height="40" 
                   Fill="{Binding RelativeSource={RelativeSource FindAncestor, 
                                      AncestorType={x:Type Border},                                          
                                      AncestorLevel=1},
                                      Path=BorderBrush}" />
                <TextBlock Text="Hello!" VerticalAlignment="Center" FontSize="24" Width="120"
                           TextAlignment="Center"
                   Foreground="{Binding RelativeSource={RelativeSource FindAncestor, 
                                            AncestorType={x:Type Border},
                                            AncestorLevel=1},
                                            Path=Background}" 
                   Background="{Binding RelativeSource={RelativeSource FindAncestor, 
                                             AncestorType={x:Type Grid},
                                             AncestorLevel=1},
                                            Path=Background}" />
            </StackPanel>
        </Border>
    </Grid>
</Window>


このサンプルでは、RelativeSource を3か所で利用しています。
■1つ目
Hello!という文字列の左横にRectangleが表示されていますが、このFillプロパティをRelativeSource を使い、親要素の BorderのBorderBrush と同じになるようにしています。
その指定部分を以下に示します。

    Fill="{Binding RelativeSource={RelativeSource FindAncestor,
                   AncestorType={x:Type Border},                                       
                   AncestorLevel=1},
                   Path=BorderBrush}" />

FindAncestorは、親の要素を検索するモードです。型およびでレベル(オプション)を指定します。
AncestorTypeは、検索する親要素の型を指定します。
AncestorLevelには、検索する親のレベルを設定します。バインディング ターゲット要素に一番近いレベルを示すには、1 を使用します。つまり、1の場合は、親を辿っていき一番最初に見つかった要素を適用するということです。

■2つ目
Hello!文字列(TextBlock)の文字の色(Forground)を親要素のBorderのBackgroundと同一になるようにしています。

■3つ目
Hello!文字列(TextBlock)の背景色(Background)を親要素のGridのBackgroundと同一になるようにしています。


WPFサンプル・目次
  
Posted by gushwell at 21:42Comments(0)TrackBack(0)

2013年07月18日

WPFサンプル:DataTemplateでカスタムクラスのデータの表示形式を定義する

   このエントリーをはてなブックマークに追加 Clip to Evernote
前回は、DateTimeの表示形式をDataTemplateで定義しましたが、今度はカスタムクラスの表示をDataTemplateで定義してみます。

以下のようなカスタムクラスを定義します。
サンプルが複雑にならないように、2つのプロパティを持つ簡単なクラスとしました。

public class MyImage {
    public string Name { get; set; }
    public BitmapImage Bitmap { get; set; }
}

このクラスに対するDataTemplateを定義し、その中で、Nameプロパティと、Bitmapプロパティをバインド指定します。
今回は、利用するコントロールをContentControlとしました。このコントロールは、コンテンツを持つコントロールの基底クラスで、独自のコントロールを定義する場合や、DataTemplateを使った表示のみを行う場合などに利用できます。

<Window x:Class="DataTemplateSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:local="clr-namespace:DataTemplateSample"
        Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
    <Window.Resources>
        <DataTemplate DataType="{x:Type local:MyImage}">
            <StackPanel Name="stackPanel1" Orientation="Horizontal">
                <Image Height="80" Stretch="Uniform" Source="{Binding Bitmap}"/>
                <Label Content="{Binding Name}" FontSize="14" VerticalAlignment="Center"/>
            </StackPanel>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <ContentControl Name="myImage" Content="{Binding}" Height="80" />
    </Grid>
</Window>

C#側のコードは、MyImageオブジェクトを生成し、myImageのDataContextに設定しているだけです。
どのような形式で表示するかは、XAMLのDataTemplate側で指定していますから、コード側では、画像を表示するとか、名前を表示するといった指定はありません。DataContextにセットしているだけです。

using System;
using System.Windows;
using System.Windows.Media.Imaging;
namespace DataTemplateSample {
    public partial class MainWindow : Window {
        public MainWindow() {
            InitializeComponent();
        }
        private void Window_Loaded(object sender, RoutedEventArgs e) {
            MyImage mi = new MyImage();
            mi.Name = @"コスモス";
            mi.Bitmap = new BitmapImage();
            mi.Bitmap.BeginInit();
            Uri uri = new Uri("Images/SampleImage.jpg", UriKind.Relative);
            mi.Bitmap.UriSource = uri;
            mi.Bitmap.EndInit();
            myImage.DataContext = mi;
        }
    }
}

実行結果です。

dataTemplate2

ちなみに、Windows_Loaded イベントハンドラを記述せずに、XAMLだけで書くとすると以下のように書けます。
このとき、C#で追加記述するのは、MyImage クラスだけとなります。

<Window x:Class="DataTemplateSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:DataTemplateSample"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <DataTemplate DataType="{x:Type local:MyImage}">
            <StackPanel Name="stackPanel1" Orientation="Horizontal">
                <Image Height="80" Stretch="Uniform" Source="{Binding Bitmap}"/>
                <Label Content="{Binding Name}" FontSize="14" VerticalAlignment="Center"/>
            </StackPanel>
        </DataTemplate>
    </Window.Resources>
    <Window.DataContext>
        <local:MyImage  Name="コスモス">
            <local:MyImage.Bitmap>
                <BitmapImage UriSource="Images/SampleImage.jpg" />
            </local:MyImage.Bitmap>
        </local:MyImage>
    </Window.DataContext>
    <Grid>
        <ContentControl Name="myImage" Content="{Binding Mode=OneWay}" Height="80" />
    </Grid>
</Window>


WPFサンプル・目次
  
Posted by gushwell at 23:10Comments(0)TrackBack(0)

2013年07月15日

WPFサンプル:DataTemplateでデータの表示形式を定義する

   このエントリーをはてなブックマークに追加 Clip to Evernote
DataTemplateを使うと、データの視覚的表現を定義することができます。
例えば、あるオブジェクトの表現を数値であらわすか、文字列であらわすか、それともグラフィックスで表すかは、視覚的表現の部分です。DataTemplateを使うことで、このどういった表現で表示するのかを指定できます。

DateTime型のオブジェクトの表示をカスタマイズするサンプルを書いてみました。

まずは、C#のコードから。

using System;
using System.Windows;
namespace DataTemplate1Sample {
    public partial class MainWindow : Window {
        public MainWindow() {
            InitializeComponent();
        }
        private void Window_Loaded_1(object sender, RoutedEventArgs e) {
            label1.Content = DateTime.Now;
        }
    }
}

C#のコードでは、label1.DataContextに DateTime.Nowをセットしているだけです。
つまり、コードでは日付を表示することだけに集中し、どのように表示するかは、XAML側に任せてしまおうということです。

どのように表示するかは、以下に示すように XAMLのDataTemplateで指定します。

<Window x:Class="DataTemplate1Sample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:system="clr-namespace:System;assembly=mscorlib"
        Title="MainWindow" Height="150" Width="525" Loaded="Window_Loaded_1">
    <Window.Resources>
        <DataTemplate DataType="{x:Type system:DateTime}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Path=Year}"></TextBlock>
                <TextBlock Text="年"></TextBlock>
                <TextBlock Text="{Binding Path=Month}"></TextBlock>
                <TextBlock Text="月"></TextBlock>
                <TextBlock Text="{Binding Path=Day}"></TextBlock>
                <TextBlock Text="日"></TextBlock>
            </StackPanel>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <Label Height="40" FontSize="20" Name="label1" Content="{Binding}"/>
    </Grid>
</Window>

Windows.Resources要素に記述した DataTemplateの定義では、DataTypeでDateTime型のDataTemplateであることを指定しています。XAMLにDateTime型を認識させるために、名前空間を利用しています。
そして、DataTemplateの子要素としてどのような表示にするのかを指定しています。ここでは、StackPanelのなかにTextBlockを複数配置し、TextプロパティとDateTimeのYear, Month, Dayプロパティとをバインドさせています。

実行結果を示します。

dataTemplate1

WPFサンプル・目次
  
Posted by gushwell at 22:00Comments(0)TrackBack(0)

2013年07月11日

WPFサンプル:起点サイトファイルを扱う

   このエントリーをはてなブックマークに追加 Clip to Evernote
これまでリソースファイルコンテンツファイルのサンプルを示しましたが、今回は、起点サイトファイルのサンプルです。

起点サイトファイルは、コンテンツファイルと同様、アセンブリには組み込まれませんが、コンテンツファイルとは異なり、明示的な関係を持っていません。そのため、起点サイトファイルは「ビルド時にファイルが存在しない場合」や「実行時になるまで、どんなファイルが必要になるかわからない場合」に利用されます。

起点サイトファイルを利用するには、ビルド時にデータファイルが用意できる場合には、プロジェクトにファイルを追加し、[ビルドアクション]を[なし]に設定します。

前回と同様、アプリケーションの起動場所に、[data]ディレクトリを作成し、そこに 以下の people.xmlを置いた場合の例を示します。

<?xml version="1.0" encoding="utf-8"?>
<People>
  <Person IsReal="true">
    <Name>坂本竜馬</Name>
    <Age>35</Age>
  </Person>
  <Person IsReal="true">
    <Name>井伊直弼</Name>
    <Age>44</Age>
  </Person>
  <Person IsReal="false">
    <Name>明智小五郎</Name>
    <Age>39</Age>
  </Person>
  <Person IsReal="true">
    <Name>勝海舟</Name>
    <Age>18</Age>
  </Person>
  <Person IsReal="true">
    <Name>西郷隆盛</Name>
    <Age>52</Age>
  </Person>
</People>
起点サイトファイルを読み込むには、ApplicationクラスのGetRemoteStreamメソッドを利用します。 以下C#のコードです。 ここでは、MainWindowコンストラクタで、xmlファイルを読み込み ListBoxにバインドしています。
using System;
using System.Linq;
using System.Windows;
using System.Xml.Linq;
namespace SiteOfOriginFilesSample {
    public partial class MainWindow : Window {
        public MainWindow() {
            InitializeComponent();
            Uri uri = new Uri("data/people.xml", UriKind.Relative);
            var info = Application.GetRemoteStream(uri);
            XDocument xdoc = XDocument.Load(info.Stream, LoadOptions.None);
            listBox1.ItemsSource = from xperson in xdoc.Root.Elements()
                                   select xperson.Element("Name").Value;
        }
    }
}

UriKind .Absolute を指定した場合は、以下のように URIを指定します。

Uri uri = new Uri( @"pack://siteoforigin:,,,/data/people.xml" , UriKind .Absolute);

以下実行結果とXAMLです。

SiteOfOrigin

<Window x:Class="SiteOfOriginFilesSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ListBox x:Name="listBox1" HorizontalAlignment="Stretch"
                 VerticalAlignment="Stretch" />
    </Grid>
</Window>


WPFサンプル・目次
  
Posted by gushwell at 22:35Comments(0)TrackBack(0)