none
Window.Resourcesの、C#での記述が分かりません RRS feed

  • 質問

  • お世話になります。

    以下のXAMLをC#で記述したいのですが書き方が分かりません。。。
    特にWindow.Resources内が分かりません。

    ※XAMLは、ウェブ上で参考にしたソースです。


    <Window x:Class="WpfApplication1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:my="clr-namespace:WpfApplication1"
        Title="Window1" Height="300" Width="300">
    
    <Window.Resources>
    
            <!--リサイズハンドル用のテンプレート定義-->
            <ControlTemplate TargetType="Thumb" x:Key="ResizeHandleTemplate">
                <Ellipse Width="10" Height="10" Margin="-3"
                         Stroke="DimGray" Fill="LightSteelBlue"/>
            </ControlTemplate>
    
            <!--装飾用のテンプレート定義-->
            <ControlTemplate x:Key="AdornerTemplate">
                <Grid>
                    <Thumb Name="ResizeThumb_LT" 
                           HorizontalAlignment="Left" VerticalAlignment="Top"
                           Template="{StaticResource ResizeHandleTemplate}"
                           DragDelta="ResizeThumb_DragDelta"/>
                    <Thumb Name="ResizeThumb_RT" 
                           HorizontalAlignment="Right" VerticalAlignment="Top"
                           Template="{StaticResource ResizeHandleTemplate}"
                           DragDelta="ResizeThumb_DragDelta"/>
                    <Thumb Name="ResizeThumb_LB" 
                           HorizontalAlignment="Left" VerticalAlignment="Bottom"
                           Template="{StaticResource ResizeHandleTemplate}"
                           DragDelta="ResizeThumb_DragDelta"/>
                    <Thumb Name="ResizeThumb_RB" 
                           HorizontalAlignment="Right" VerticalAlignment="Bottom"
                           Template="{StaticResource ResizeHandleTemplate}"
                           DragDelta="ResizeThumb_DragDelta"/>
                </Grid>
            </ControlTemplate>
    
        </Window.Resources>
        
        <Canvas>
            <!--フォーカスで装飾を有効にする場合-->
            <Button Name="Target2"
                    Canvas.Left="100" Canvas.Top="80"
                    Width="100" Height="40"
                    Content="フォーカスで">
                <Button.Style>
                    <Style TargetType="Button">
                        <Style.Triggers>
                            <Trigger Property="IsFocused" Value="True">
                                <Setter Property="my:AdornedBy.Template"
                                        Value="{StaticResource AdornerTemplate}"/>
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </Button.Style>
            </Button>
       </Canvas>
        
    </Window>
    


    2012年8月17日 9:13

回答

  • >> ボタンクリックなどあるイベント発生度に
    >> 動的にEllipseを生成したいです。

    なるほど。そういう場合でも、全部コードビハインドで書く必要はないですよ。
    とりあえず、最初のコードのResource定義を(可能な限り)適用する方向でサンプルを書いてみました。

    <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="350" Width="525">
        
        <Window.Resources>
            <ControlTemplate TargetType="Thumb" x:Key="ResizeHandleTemplate">
                <Ellipse Width="10" Height="10" Margin="-3"
                         Stroke="DimGray" Fill="LightSteelBlue"/>
            </ControlTemplate>
    
            <ControlTemplate x:Key="AdornerTemplate">
                <Grid>
                    <Thumb Name="ResizeThumb_LT" 
                           HorizontalAlignment="Left" VerticalAlignment="Top"
                           Template="{StaticResource ResizeHandleTemplate}"/>
                    <Thumb Name="ResizeThumb_RT" 
                           HorizontalAlignment="Right" VerticalAlignment="Top"
                           Template="{StaticResource ResizeHandleTemplate}"/>
                    <Thumb Name="ResizeThumb_LB" 
                           HorizontalAlignment="Left" VerticalAlignment="Bottom"
                           Template="{StaticResource ResizeHandleTemplate}"/>
                    <Thumb Name="ResizeThumb_RB" 
                           HorizontalAlignment="Right" VerticalAlignment="Bottom"
                           Template="{StaticResource ResizeHandleTemplate}"/>
                </Grid>
            </ControlTemplate>
            
            <Style x:Key="AddButtonStyle" TargetType="Button">
                <Style.Triggers>
                    <Trigger Property="IsFocused" Value="True">
                        <Setter Property="Template" Value="{StaticResource AdornerTemplate}"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Window.Resources>
        
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            
            <Button Grid.Row="0" Content="Add" Click="Button_Click"/>
            <WrapPanel Name="wrapPanel" Grid.Row="1">
                
            </WrapPanel>
        </Grid>
    </Window>


        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                wrapPanel.Children.Add(new Button
                {
                    Style = this.Resources["AddButtonStyle"] as Style,
                    Width = 40,
                    Height = 100,
                    Content = "フォーカスで"
                });
            }
        }

    こんな感じですかね。イベントとかで何やってるのかはわからなかったので、そこは外してます。
    要するに、動的生成するコントロール(Button)のStyleを、XAMLで定義したResourceから引っ張ってくるということです。
    動的生成だからといって全部が全部をコードビハインドで書く必要はなく、適宜XAMLと組み合わせる方が遙かに楽ですよ(笑)
    ちなみに定義されているコントロールですが、コントロール内で挙動を完結できるのであればユーザーコントロールを作った方がなお良いでしょうね。

    あと、これはあくまでも私の考え方なんですが、XAMLで書けるところは可能な限りXAMLで書いて、コードビハインドは最小限にするのがいいかなー、と思います。



    • 編集済み みっと 2012年8月17日 13:32
    • 回答としてマーク sumi_sumi 2012年8月20日 2:55
    2012年8月17日 13:31

すべての返信

  • できなくはないんですけど、すんごい手間ですよ?(苦笑)

    とりあえず
    >> <!--リサイズハンドル用のテンプレート定義-->
    の部分だけコードビハインドにして書いてみました。

            public MainWindow()
            {
                InitializeComponent();
    
                FrameworkElementFactory factory = new FrameworkElementFactory(typeof(Ellipse));
                factory.SetValue(Ellipse.WidthProperty, 10);
                factory.SetValue(Ellipse.HeightProperty, 10);
                factory.SetValue(Ellipse.MarginProperty, new Thickness(3));
                factory.SetValue(Ellipse.StrokeProperty, Brushes.DimGray);
                factory.SetValue(Ellipse.FillProperty, Brushes.LightSteelBlue);
    
                ControlTemplate template = new ControlTemplate(typeof(Thumb)) { VisualTree = factory };
    
                this.Resources.Add("ResizeHandleTemplate", template);
            }
    
    あの記述だけでこんなコード量になるので、特別な理由があってどうしても、ということでなければXAMLで書くことをお勧めします。
    2012年8月17日 9:58
  • みっとさま

    ありがとうございます。

    ボタンクリックなどあるイベント発生度に
    動的にEllipseを生成したいです。


    こういったシチュエーションの場合、
    XAMLでの記述が分からず、C#での~となってしまいました。


    WPF暦、ほんと浅いです(T_T)

    2012年8月17日 11:24
  • 何がしたいのかいまいちわからないので外れてるかもしれませんが、XAMLで書ける範囲内のことならXAMLで書いてパースするという手もあります。

    var template = 
        "<Window " +
            "xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" " +
            "xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" " +
            "Title=\"Window1\" Height=\"300\" Width=\"300\">" +
            "<Button Content=\"OK\" />" +
        "</Window>";
    
    var r = new XamlReader();
    var window = (Window)r.LoadAsync(new MemoryStream(Encoding.UTF8.GetBytes(template)));
    window.Show();
    


    かずき Blog:http://d.hatena.ne.jp/okazuki/

    2012年8月17日 13:31
  • >> ボタンクリックなどあるイベント発生度に
    >> 動的にEllipseを生成したいです。

    なるほど。そういう場合でも、全部コードビハインドで書く必要はないですよ。
    とりあえず、最初のコードのResource定義を(可能な限り)適用する方向でサンプルを書いてみました。

    <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="350" Width="525">
        
        <Window.Resources>
            <ControlTemplate TargetType="Thumb" x:Key="ResizeHandleTemplate">
                <Ellipse Width="10" Height="10" Margin="-3"
                         Stroke="DimGray" Fill="LightSteelBlue"/>
            </ControlTemplate>
    
            <ControlTemplate x:Key="AdornerTemplate">
                <Grid>
                    <Thumb Name="ResizeThumb_LT" 
                           HorizontalAlignment="Left" VerticalAlignment="Top"
                           Template="{StaticResource ResizeHandleTemplate}"/>
                    <Thumb Name="ResizeThumb_RT" 
                           HorizontalAlignment="Right" VerticalAlignment="Top"
                           Template="{StaticResource ResizeHandleTemplate}"/>
                    <Thumb Name="ResizeThumb_LB" 
                           HorizontalAlignment="Left" VerticalAlignment="Bottom"
                           Template="{StaticResource ResizeHandleTemplate}"/>
                    <Thumb Name="ResizeThumb_RB" 
                           HorizontalAlignment="Right" VerticalAlignment="Bottom"
                           Template="{StaticResource ResizeHandleTemplate}"/>
                </Grid>
            </ControlTemplate>
            
            <Style x:Key="AddButtonStyle" TargetType="Button">
                <Style.Triggers>
                    <Trigger Property="IsFocused" Value="True">
                        <Setter Property="Template" Value="{StaticResource AdornerTemplate}"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Window.Resources>
        
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            
            <Button Grid.Row="0" Content="Add" Click="Button_Click"/>
            <WrapPanel Name="wrapPanel" Grid.Row="1">
                
            </WrapPanel>
        </Grid>
    </Window>


        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                wrapPanel.Children.Add(new Button
                {
                    Style = this.Resources["AddButtonStyle"] as Style,
                    Width = 40,
                    Height = 100,
                    Content = "フォーカスで"
                });
            }
        }

    こんな感じですかね。イベントとかで何やってるのかはわからなかったので、そこは外してます。
    要するに、動的生成するコントロール(Button)のStyleを、XAMLで定義したResourceから引っ張ってくるということです。
    動的生成だからといって全部が全部をコードビハインドで書く必要はなく、適宜XAMLと組み合わせる方が遙かに楽ですよ(笑)
    ちなみに定義されているコントロールですが、コントロール内で挙動を完結できるのであればユーザーコントロールを作った方がなお良いでしょうね。

    あと、これはあくまでも私の考え方なんですが、XAMLで書けるところは可能な限りXAMLで書いて、コードビハインドは最小限にするのがいいかなー、と思います。



    • 編集済み みっと 2012年8月17日 13:32
    • 回答としてマーク sumi_sumi 2012年8月20日 2:55
    2012年8月17日 13:31
  • みっとさま

    有難う御座います。具体的なコードで解決です。
    XAMLがまだ全部理解出来ていません。
    少しずつ解読して勉強させていただきます。


    そして知りたいことは、まさしくこういうことでした。

    単にコードだけでなく指針、考え方まで教えていただきまして有難う御座います。


    何となく見た目に関するものは極力XAMLへと思っていましたが、具体的に書けず・・・でした。

    本当に参考になりました。
    有難う御座います。
    2012年8月20日 2:55
  • かずきさま

    アドバイス有難う御座います。

    そういう方法もあるのですね・・・。

    また違う機会に採用させてください。

    参考になりました。
    有難うございます。
    2012年8月20日 3:01