2

基本的に、私が持っているのは単純な警告メッセージのセットアップです。テキストと色 (成功の場合は緑、エラーの場合は赤など) の VM へのデータ バインディングを含む個々のアラートのビューがあります。

<Border Margin="0 0 0 20" Background="{Binding Path=BackgroundColor}" BorderBrush="#D4D4D4" BorderThickness="1" CornerRadius="8">
    <Border.Effect>
        <DropShadowEffect Color="DarkGray"/>
    </Border.Effect>
<Grid >
        <Button Content="X" HorizontalAlignment="Left" 
            Margin="268,10,0,0" VerticalAlignment="Top" Width="20" RenderTransformOrigin="-0.48,0.727"/>
        <TextBlock x:Name="Message" 
           Foreground="White" FontWeight="SemiBold" FontSize="13px"
           Text="{Binding Path=Message}" 
           HorizontalAlignment="Left" Width="250"
           TextWrapping="Wrap"
           VerticalAlignment="Center" RenderTransformOrigin="-4.395,-0.038" Margin="7,13,0,25"/>
    </Grid>
</Border>

目標は、「X」ボタンをクリックしたときにそれらが消え、素敵なフェード アニメーションが表示されるようにすることです。フェードを処理するためのストーリーボードがあります。

<UserControl.Triggers>
    <EventTrigger RoutedEvent="Button.Click">
        <BeginStoryboard>
            <Storyboard>
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)">
                    <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
                    <EasingDoubleKeyFrame KeyTime="0:0:1" Value="0"/>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>
        </BeginStoryboard>
    </EventTrigger>
</UserControl.Triggers>

ここで、私がやりたかったのは、Caliburn.Micro をストーリーボードのCompletedイベントにフックして、実際のビューを非表示にする方法です (別のビューにこれらのアラートのバインド可能なコレクションがあり、アラートがスタックされてから破棄されるようにするためです)。ユーザーの希望)。

最初は、他のバインディングと同じように機能すると考えて、次のようなものを試しました。

<Storyboard cal:Message.Attach="[Event Completed] = [Action DismissMessage($source, $eventArgs)]">
<!-- rest of the codez... -->

しかし、次のエラーが発生しました:

Cannot attach type "ActionMessage" to type "Storyboard". Instances of type "ActionMessage" can only be attached to objects of type "FrameworkElement".

そして、これは十分に理にかなっていると思います...しかし、このバインディングのようなものを処理する最良の方法は何ですか? 私の心は必然的に、ビューの分離コードからビューモデルを呼び出すなどのハックな解決策を試みることに迷い始めますが、それは MVVM に違反しているようです。

助言がありますか?

4

3 に答える 3

2

私がコメントしたように、より簡単な方法はアグリゲーターかもしれません。

完了したらStoryBoard、アグリゲーター (またはダイアログ用の特定のアグリゲーター) を介してイベントを発生させ、VM でそれを処理してダイアログを閉じることができます。

たとえば、アグリゲーターがない場合は、アグリゲーターを提供するものが必要になります (DI を使用しているかどうかは不明です)。

public static DialogEventAggregatorProvider  
{
    public static EventAggregator { get; set; } // Obviously instantiate this, I'll leave the code out for brevity
}

あなたのビューのコードビハインドで:

public SomeView : UserControl
{
    private void StoryBoard_Completed(object sender, SomeEventArgs e)
    {
        DialogEventAggregatorProvider.EventAggregator.Publish(new CloseDialogMessage()); // Add some args or what have you if it helps identify what dialog to close, but try not to break MVVM ;)
    }
}

VM で

public SomeViewModel : Screen, IHandle<CloseDialogMessage>
{
    public SomeViewModel() 
    {
        // Don't forget to subscribe or you'll be scratching your head
        DialogEventAggregatorProvider.EventAggregator.Subscribe(this);
    }

    public void Handle(CloseDialogMessage message) 
    { 
        // if(message.HasSomeValue) Here you could check the type of message etc.
           TryClose();
    }
}

それほどきれいではありませんが、実装を汎用に保つ限り、MVVM の原則に違反することなく回避できます。

于 2013-02-25T15:38:03.873 に答える
0

Marlon Grech Attached Command Behaviorsライブラリを使用して、そのイベントをコマンドにバインドできます。

ライブラリはここからダウンロードできます:http: //marlongrech.wordpress.com/2008/12/13/attachedcommandbehavior-v2-aka-acb/

于 2013-02-22T19:09:20.077 に答える