【解決方法】WPF で、変更可能な値を分離コードから XAML のアニメーションにバインドするにはどうすればよいですか?


求められる状態は次のとおりです。
共通のキャンバス上に重なって配置されるコンテナ (ボーダー) はありません。 選択した境界線を左クリックすると、アニメーションによって拡大され、他のすべての境界線も同時にズームアウト/移動されます。 すべての境界線は、最後の位置/サイズから新しい位置/サイズにスムーズにアニメーション化されます。
いずれかの境界線を右クリックすると、すべての境界線がデフォルトの場所/サイズにアニメーション化されます (戻されます)。
いずれかの境界線をクリックすると、最終的に到達する各境界線の異なる位置/サイズ値のセットが分離コードで定義されます。 これらの新しい値はアニメーションに渡される/バインドされる(はずです)。

私は WPF を初めて使いますが、このタスクで到達した状態は次のとおりです。
プログラムの開始直後に境界線を最初にクリックすると、必要なアニメーションの位置/サイズの変更が行われます。 ただし、その後に続く他のクリックは、クリック イベントの後にコードビハインドで定義された値を変更することなく、最初と同じことを繰り返すだけです。 さらに、この最初の最終的な位置/サイズも正しくアニメーション化されますが、アニメーションが境界線から「ActualValues」を読み取っていないのと同様に、INITIAL 値は「外側」(画面の後ろ) から取得されます。

Wrappanel やスタイルを使用した、より良い他の解決策を探しているわけではありません。 動的に変更可能な値を分離コードから XAML 定義のアニメーションに渡す方法を探しています。

私が試したこと:

これは WPF の簡略化された例です。

Imports System.Windows.Media.Animation

Public Class Window_NAS_HVZ

    Public Property Border1_Wid As Double
    Public Property Border1_Hgh As Double
    Public Property Border1_Top As Double
    Public Property Border1_Left As Double
    Public Property Border2_Wid As Double
    Public Property Border2_Hgh As Double
    Public Property Border2_Top As Double
    Public Property Border2_Left As Double
    Public Property Border3_Wid As Double
    Public Property Border3_Hgh As Double
    Public Property Border3_Top As Double
    Public Property Border3_Left As Double

    Public Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Loaded
        DataContext = Me
    End Sub

    Public Sub Zoom_SIZE_default_Click(sender As Object, e As RoutedEventArgs)
        Border1_Wid = 400 : Border1_Hgh = 200 : Border1_Top = 20 : Border1_Left = 50
        Border2_Wid = 400 : Border2_Hgh = 200 : Border2_Top = 240 : Border2_Left = 50
        Border3_Wid = 400 : Border3_Hgh = 200 : Border3_Top = 460 : Border3_Left = 50
        BeginStoryboard(TryCast(FindResource("Borders_Resize"), Storyboard))
    End Sub

    Public Sub Zoom_SIZE_1_Click(sender As Object, e As RoutedEventArgs)
        Border1_Wid = 400 : Border1_Hgh = 500 : Border1_Top = 20 : Border1_Left = 50
        Border2_Wid = 200 : Border2_Hgh = 50 : Border2_Top = 540 : Border2_Left = 150
        Border3_Wid = 200 : Border3_Hgh = 50 : Border3_Top = 610 : Border3_Left = 150
        BeginStoryboard(TryCast(FindResource("Borders_Resize"), Storyboard))
    End Sub

    Public Sub Zoom_SIZE_2_Click(sender As Object, e As RoutedEventArgs)
        Border1_Wid = 200 : Border1_Hgh = 50 : Border1_Top = 20 : Border1_Left = 150
        Border2_Wid = 400 : Border2_Hgh = 500 : Border2_Top = 90 : Border2_Left = 50
        Border3_Wid = 200 : Border3_Hgh = 50 : Border3_Top = 610 : Border3_Left = 150
        BeginStoryboard(TryCast(FindResource("Borders_Resize"), Storyboard))
    End Sub
    Public Sub Zoom_SIZE_3_Click(sender As Object, e As RoutedEventArgs)
        Border1_Wid = 200 : Border1_Hgh = 50 : Border1_Top = 20 : Border1_Left = 150
        Border2_Wid = 200 : Border2_Hgh = 50 : Border2_Top = 90 : Border2_Left = 150
        Border3_Wid = 400 : Border3_Hgh = 500 : Border3_Top = 160 : Border3_Left = 50
        BeginStoryboard(TryCast(FindResource("Borders_Resize"), Storyboard))
    End Sub

End Class

これがその XAML です。

<Window x:Class="Window_NAS_HVZ"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Width="600" Height="800"  
        DataContext="{Binding RelativeSource={RelativeSource Self}}">

    <Window.Resources>
        <Storyboard x:Key="Borders_Resize">
            <DoubleAnimation Storyboard.TargetName="BORDER_1" Storyboard.TargetProperty="(Border.Height)" Duration="0:0:0.2" From="{Binding ActualHeight}" To="{Binding Path=Border1_Hgh}"/>
            <DoubleAnimation Storyboard.TargetName="BORDER_2" Storyboard.TargetProperty="(Border.Height)" Duration="0:0:0.2" From="{Binding ActualHeight}" To="{Binding Path=Border2_Hgh}"/>
            <DoubleAnimation Storyboard.TargetName="BORDER_3" Storyboard.TargetProperty="(Border.Height)" Duration="0:0:0.2" From="{Binding ActualHeight}" To="{Binding Path=Border3_Hgh}"/>
            <DoubleAnimation Storyboard.TargetName="BORDER_1" Storyboard.TargetProperty="(Border.Width)" Duration="0:0:0.2" From="{Binding ActualWidth}" To="{Binding Path=Border1_Wid}"/>
            <DoubleAnimation Storyboard.TargetName="BORDER_2" Storyboard.TargetProperty="(Border.Width)" Duration="0:0:0.2" From="{Binding ActualWidth}" To="{Binding Path=Border2_Wid}"/>
            <DoubleAnimation Storyboard.TargetName="BORDER_3" Storyboard.TargetProperty="(Border.Width)" Duration="0:0:0.2" From="{Binding ActualWidth}" To="{Binding Path=Border3_Wid}"/>
            <DoubleAnimation Storyboard.TargetName="BORDER_1" Storyboard.TargetProperty="(Canvas.Top)" Duration="0:0:0.2" From="{Binding Actual.Canvas.Top}" To="{Binding Path=Border1_Top}"/>
            <DoubleAnimation Storyboard.TargetName="BORDER_2" Storyboard.TargetProperty="(Canvas.Top)" Duration="0:0:0.2" From="{Binding Actual.Canvas.Top}" To="{Binding Path=Border2_Top}"/>
            <DoubleAnimation Storyboard.TargetName="BORDER_3" Storyboard.TargetProperty="(Canvas.Top)" Duration="0:0:0.2" From="{Binding Actual.Canvas.Top}" To="{Binding Path=Border3_Top}"/>
            <DoubleAnimation Storyboard.TargetName="BORDER_1" Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:0.2" From="{Binding Actual.Canvas.Left}" To="{Binding Path=Border1_Left}"/>
            <DoubleAnimation Storyboard.TargetName="BORDER_2" Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:0.2" From="{Binding Actual.Canvas.Left}" To="{Binding Path=Border2_Left}"/>
            <DoubleAnimation Storyboard.TargetName="BORDER_3" Storyboard.TargetProperty="(Canvas.Left)" Duration="0:0:0.2" From="{Binding Actual.Canvas.Left}" To="{Binding Path=Border3_Left}"/>
        </Storyboard>
    </Window.Resources>
  
    <Grid >
        <Viewbox >
            <Canvas  Background="White" Width="500" Height="680">
                <Border  x:Name="BORDER_1" Width="400"  Height="200" Background="Green"  Canvas.Left="50"  Canvas.Top="20" 
                         MouseLeftButtonDown ="Zoom_SIZE_1_Click"
                         MouseRightButtonDown ="Zoom_SIZE_default_Click"
                         Opacity="0.5">
                </Border>

                <Border  x:Name="BORDER_2" Background="Red" Width="400"  Height="200"  Canvas.Left="50"  Canvas.Top="240"
                         MouseLeftButtonDown ="Zoom_SIZE_2_Click"
                         MouseRightButtonDown ="Zoom_SIZE_default_Click"
                         Opacity="0.5">
                </Border>

                <Border  x:Name="BORDER_3" Background="Blue"  Width="400"  Height="200"  Canvas.Left="50" Canvas.Top="460"
                         MouseLeftButtonDown ="Zoom_SIZE_3_Click"
                         MouseRightButtonDown ="Zoom_SIZE_default_Click"
                         Opacity="0.5" >
                </Border>
            </Canvas>
        </Viewbox>
    </Grid>
</Window>

これが望ましい状態の画像です:
http://www.z7h.sk/resizeborders.jpg
1 – デフォルトの位置 (右クリック後)
2 – 上部の境界線を左クリックした後
3 – 中央の境界線を左クリックした後
4 – 下の境界線を左クリックした後

コメント

タイトルとURLをコピーしました