none
Binding完了前の段階でInteractionRequestTriggerのRequestを実行しても、Bindingが完了したタイミングで実行されるようにしたい。 RRS feed

  • 質問

  • ViewとViewModelのBindingが完了前の段階でViewModel側で実行されたInteractionRequestTriggerのInteractionRequestを実行したとしても、Bindingが完了した時点で、InteractionRequestTriggerに設定されているActionを実行したいと考えています。


    TestWindow.xaml 今回の対象のView
    <Window x:Class="Sample.TestWindow"
            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"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
            xmlns:prism="http://prismlibrary.com/"
            xmlns:local="clr-namespace:Sample"
            mc:Ignorable="d"
            Title="TestWindow" Height="300" Width="300">
        <StackPanel>
            <TextBlock Text="テストWindow">
                <i:Interaction.Triggers>
                    <prism:InteractionRequestTrigger SourceObject="{Binding TestRequest}">
                        <local:TestAction/>
                    </prism:InteractionRequestTrigger>
                </i:Interaction.Triggers>
            </TextBlock>
        </StackPanel>
    </Window>
    TestAction.cs
        public class TestAction : TriggerAction<TextBlock>
        {
            protected override void Invoke(object parameter)
            {
                Console.WriteLine("Action実行");
            }
        }
    TestViewModel.cs 今回の対象のViewModel
        public class TestViewModel
        {
            public InteractionRequest<INotification> TestRequest { get; }
    
            public TestViewModel()
            {
                TestRequest = new InteractionRequest<INotification>();
            }
    
    
            public void RaiseTestRequest()
            {
                TestRequest.Raise(new Notification());
            }
        }

    このViewとViewModelを使って表示します。

    MainWindow.xaml 起動時の画面

    <Window x:Class="Sample.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"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:Sample"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="525">
        <StackPanel>
            <Button Content="Show" Click="Button_Click"/>
        </StackPanel>
    </Window>
    MainWindow.xaml.cs
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                var view = new TestWindow();
    
                var viewModel = new TestViewModel();
                viewModel.RaiseTestRequest(); //★前提としてBinding前にここで発火しておく必要があります。
    
                view.DataContext = viewModel; //その後DataContextにセット
    
                view.Show();
            }
        }

    上記コードでは、実行してもTestAction.csの「Action実行」は出力されません。

    (Binding前に実行されたInteractionRequestのため)

    Binding前にInteractionRequestを実行していても、Bindingが完了された時点でそれまでの段階でInteractionRequestが実行されていればActionが実行されるようにするために良い方法はないでしょうか。

    ご教授いただけると幸いです。









    • 編集済み yj0529 2019年5月23日 12:34
    2019年5月23日 12:25

回答

  • DispatcherPriority.DataBind以下の優先度でBeginInvokeするとか

    public void RaiseTestRequest(System.Windows.Threading.DispatcherPriority priority = System.Windows.Threading.DispatcherPriority.Normal)
    {
        if (priority != System.Windows.Threading.DispatcherPriority.Normal)
        {
            System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
            {
                TestRequest.Raise(new Notification());
            }), priority);
        }
        else
        {
            TestRequest.Raise(new Notification());
        }
    }

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク yj0529 2019年5月24日 1:25
    2019年5月23日 13:49

すべての返信

  • DispatcherPriority.DataBind以下の優先度でBeginInvokeするとか

    public void RaiseTestRequest(System.Windows.Threading.DispatcherPriority priority = System.Windows.Threading.DispatcherPriority.Normal)
    {
        if (priority != System.Windows.Threading.DispatcherPriority.Normal)
        {
            System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
            {
                TestRequest.Raise(new Notification());
            }), priority);
        }
        else
        {
            TestRequest.Raise(new Notification());
        }
    }

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク yj0529 2019年5月24日 1:25
    2019年5月23日 13:49
  • gekka様

    ご提案いただいたDispatcherPriorityを変えて実行することで出力させることができました。ありがとうございます。

    2019年5月24日 1:25