A certain engineer "COMPLEX"

UWP メモ その1 EventTriggerBehaviorの制約

仕事で UWP のソフトを開発しています。そもそも WPF もそこまで経験ないのに、UWPとか無茶ぶりです。
UWP、というか WinRT 使っているとWPFでできたことができないことが多々あります。

Problem


EventTriggerAction というのがあります。
XAML側で ViewModel で定義されたメソッドをイベントと結び付けたりできます。

で、何が問題、というか結び付ける対象となるイベントに制限があります。

どうも、ルーティングイベント以外を対象にすると、下記のメッセージを含む例外を投げて実行時にクラッシュします。

System.InvalidOperationException: Adding or removing event handlers dynamically is not supported on WinRT events.
at System.Reflection.EventInfo.AddEventHandler(Object target, Delegate handler)

この現象、WPFでは発生しません。

Debugだけ?


ところが、不思議なことにReleaseビルドで実行すると、クラッシュはおろか、正しく動作します。
概要は下記のソースをみるとわかるかと。
スクロールバーを動かすと画面下部のTextBlockに乱数の値が表示されます。

ViewModel (ポータブル クラス ライブラリ)


using Microsoft.Practices.Prism.Mvvm;

namespace Shared.ViewModels
{

public sealed class MainWindowViewModel : BindableBase
{

private string _Text1;

public string Text1
{
get
{
return this._Text1;
}
set
{
SetProperty(ref this._Text1, value);
}
}

private string _Text2;

public string Text2
{
get
{
return this._Text2;
}
set
{
SetProperty(ref this._Text2, value);
}
}

public void OnScrollChanged()
{
var random = new System.Random();
this.Text1 = random.Next(0, 10000).ToString();
this.Text2 = random.Next(0, 10000).ToString();
}

}

}

MainWindow.xaml (UWP)


<Page x:Class="UWP.MainPage"
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:viewModels="using:Shared.ViewModels"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
mc:Ignorable="d">

<Page.DataContext>
<viewModels:MainWindowViewModel />
</Page.DataContext>

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<ScrollViewer x:Name="_ScrollViewer"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="ViewChanged" SourceObject="{Binding ElementName=_ScrollViewer}">
<core:CallMethodAction MethodName="OnScrollChanged" TargetObject="{Binding}"/>
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>

<Image Source="ms-appx:///Assets/kyoto.jpg" Stretch="None" />
</ScrollViewer>
<TextBlock Grid.Row="1" Text="{Binding Text1}" />
<TextBlock Grid.Row="2" Text="{Binding Text2}" />
</Grid>
</Page>

MainWindow.xaml (WPF)


<Window x:Class="WPF.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:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels1="clr-namespace:Shared.ViewModels;assembly=Shared"
Title="MainWindow"
Width="525"
Height="350"
mc:Ignorable="d">

<Window.DataContext>
<viewModels1:MainWindowViewModel />
</Window.DataContext>

<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<i:Interaction.Triggers>
<i:EventTrigger EventName="ScrollChanged">
<ei:CallMethodAction MethodName="OnScrollChanged" TargetObject="{Binding}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Image Source="Images/kyoto.jpg" Stretch="None" />
</ScrollViewer>
<TextBlock Grid.Row="1" Text="{Binding Text1}" />
<TextBlock Grid.Row="2" Text="{Binding Text2}" />
</Grid>
</Window>

実行画面 (UWP Release Build)

Release ビルド実行画面

Conclusion


原因は不明です。
仕方がないので、仕事ではコードビハインドにイベントハンドラを記述しています。

Source Code


https://github.com/takuya-takeuchi/Demo/tree/master/UWP1

コメントを残す

メールアドレスが公開されることはありません。

%d人のブロガーが「いいね」をつけました。