web-dev-qa-db-ja.com

リソースでコントロールを作成し、XAML WPFで再利用する

私は単純なシンボル/ジオメトリ/コントロールを作成して、同じウィンドウのいくつかの場所で変更して再利用しようとしています。

例:中央に円がある黒い正方形。

その後、円は赤と緑の間で変化するはずです(1つのライトのストップライトに似ています)。画像でそれを行うとうまくいきます。私はそれをWindowリソースとして解決しようとしていますが、理解できません。

アイデア:リソースに書き込みます。ここではCanvasに試します。

<Window.Resources>
    <Canvas x:Key="Ampel">
        <Rectangle Fill="Black" HorizontalAlignment="Left" Height="52" Stroke="Black"       VerticalAlignment="Top" Width="50"/>
        <Ellipse x:Name="RedGreen" Fill="Red" HorizontalAlignment="Left" Height="27" Margin="11,12,0,0" Stroke="Black" VerticalAlignment="Top" Width="28" RenderTransformOrigin="0.214,0.256"/>
    </Canvas>
</Window.Resources>

次に、それをグリッドまたはパネル内に配置したいのですが、どのように参照しますか?

<Canvas x:Name="RedGreen1" Height="50" Width="50" DataContext="{DynamicResource Ampel}" /> 

これはコンパイラエラーを返しませんが、ウィンドウには何も表示しません。また、WrapPanelなどでは機能しません。

そしてそれがうまくいくなら、円の色を変更するためのコードビヘイビアでそれをどのように参照できますか?何かのようなもの RedGreen1.RedGreen.Fill=Brushes.Green

私は信号についての記事を読みました。 UserControlを作成することが本当に必要ですか、それともwindow.resourcesでそれを解決する方法はありますか?

アプリケーションの一般的な考え方は、パラメーターのリストを用意することです。すべてのパラメーターが緑色でマークされている場合にのみ、正しい入力を持つものは緑色でマークされ、計算を開始できます。

また、赤/緑のイメージで実行しても、WPF/XAMLをよりよく理解し、何かを学ぶようにしています。

ありがとうございました。

24
user3367867

Resourcesで任意のControlを定義すると、Contentプロパティを持ち、Controlクラスから派生したControlで今後使用できます。これらは次のとおりです: ContentControlLabelContentPresenter など.

また、多くのコントロールでこのリソースを使用する場合は、リソースに x:Shared="False" を設定する必要があります。デフォルトでx:Shared="True"の場合、1つのリソースがすべてのリソースに共通です。この場合、システムは複製コンテンツを誓います。 When x:Shared="False" whenが作成されたときリクエストごとに各要素のリソース。 MSDN からの引用:

falseに設定すると、WPFリソース取得動作が変更され、属性付きリソースのリクエストがすべてのリクエストで同じインスタンスを共有するのではなく、リクエストごとに新しいインスタンスが作成されます。

例:

<Window.Resources>
    <Canvas x:Key="Ampel" x:Shared="False">
        <Rectangle Fill="Black" HorizontalAlignment="Left" Height="52" Stroke="Black" VerticalAlignment="Top" Width="50"/>
        <Ellipse x:Name="RedGreen" Fill="Red" HorizontalAlignment="Left" Height="27" Margin="11,12,0,0" Stroke="Black" VerticalAlignment="Top" Width="28" />
    </Canvas>
</Window.Resources>

<Grid>
    <ContentControl Name="MyContentControl" Content="{StaticResource Ampel}" HorizontalAlignment="Left" />        
    <Label Name="MyLabel" Content="{StaticResource Ampel}" HorizontalAlignment="Center" />
    <ContentPresenter Name="MyContentPresenter" Content="{StaticResource Ampel}" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>

コードビハインドでEllipseのFillを変更するには、次のようにします。

private void ChangeBackground_Click(object sender, RoutedEventArgs e)
{
    var canvas = MyContentControl.Content as Canvas;

    if (canvas != null)
    {
        foreach (var item in canvas.Children)
        {
            if (item is Ellipse)
            {
                ((Ellipse)item).Fill = Brushes.Green;
            }
        }
    }
}
28

canvasにはテンプレートプロパティがないため、ここでcontencontrolを使用しています。

<Window.Resources>
    <ControlTemplate x:Key="Ampel" TargetType="ContentControl">
        <Canvas>
            <Rectangle Fill="Black" HorizontalAlignment="Left" Height="52" Stroke="Black" VerticalAlignment="Top" Width="50"/>
            <Ellipse x:Name="RedGreen" Fill="{Binding Path=Tag, RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Left" Height="27" Margin="11,12,0,0" Stroke="Black" VerticalAlignment="Top" Width="28" RenderTransformOrigin="0.214,0.256"/>
        </Canvas>
    </ControlTemplate>
</Window.Resources >

<ContentControl  Template="{StaticResource Ampel}" Tag="Red" ></ContentControl>
<ContentControl  Template="{StaticResource Ampel}" Tag="Green" ></ContentControl>
<ContentControl  Template="{StaticResource Ampel}" Tag="Blue" ></ContentControl>

出力

enter image description here

5
Heena Patil