Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

FolderSelectionMessage cause InvalidOperationException in ver 3.2.3.2 #65

Closed
leon-joel opened this issue Oct 12, 2021 · 4 comments
Closed
Assignees

Comments

@leon-joel
Copy link

leon-joel commented Oct 12, 2021

LivetCask 3.2.3.2
LivetExtension 3.2.3.2

Both .NET3.1 and .NET Framework4.6.2

Exception

System.InvalidOperationException
  HResult=0x80131509
  Message=オブジェクト 'Livet.Messaging.IO.FolderSelectionMessage' は読み取り専用状態であるため、そのプロパティを設定できません。
  Source=WindowsBase
  スタック トレース:
   at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
   at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
   at Livet.Messaging.IO.FolderSelectionMessage.set_SelectedPaths(String[] value)
   at Livet.Behaviors.Messaging.IO.FolderBrowserDialogInteractionMessageAction.InvokeAction(InteractionMessage m)
   at Livet.Behaviors.Messaging.InteractionMessageAction`1.Invoke(Object parameter)
   at Microsoft.Xaml.Behaviors.TriggerAction.CallInvoke(Object parameter)
   at Microsoft.Xaml.Behaviors.TriggerBase.InvokeActions(Object parameter)
   at Livet.Behaviors.Messaging.InteractionMessageTrigger.<>c__DisplayClass21_0.<MessageReceived>b__1()
   at Livet.Behaviors.Messaging.InteractionMessageTrigger.DoActionOnDispatcher(Action action)
   at Livet.Behaviors.Messaging.InteractionMessageTrigger.MessageReceived(Object sender, InteractionMessageRaisedEventArgs e)
   at Livet.EventListeners.WeakEvents.LivetWeakEventListener`2.ReceiveEvent(WeakReference`1 listenerWeakReference, Object sender, TEventArgs args)
   at Livet.EventListeners.WeakEvents.LivetWeakEventListener`2.<>c__DisplayClass9_0.<GetStaticHandler>b__0(Object sender, TEventArgs e)
   at Livet.Messaging.InteractionMessenger.Raise(InteractionMessage message)
   at SampleAppNetCore.MainWindowViewModel.OpenFolderBrowser() in ...

Reproduction Code

MainWindow.xaml

<Window x:Class="SampleAppNetCore.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:l="http://schemas.livet-mvvm.net/2011/wpf"
        xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
        xmlns:local="clr-namespace:SampleAppNetCore"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:MainWindowViewModel/>
    </Window.DataContext>
    <i:Interaction.Triggers>
        <l:InteractionMessageTrigger MessageKey="show_selectfolderdialog" Messenger="{Binding Messenger}">
            <l:FolderBrowserDialogInteractionMessageAction/>
        </l:InteractionMessageTrigger>
    </i:Interaction.Triggers>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Menu>
            <MenuItem Header="File">
                <MenuItem Header="Open FolderBrowser" Command="{Binding OpenFolderBrowserCommand}"/>
            </MenuItem>
        </Menu>
    </Grid>
</Window>

MainWindowViewModel.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using Livet;
using Livet.Commands;
using Livet.Messaging;
using Livet.Messaging.IO;

namespace SampleAppNetCore
{
	class MainWindowViewModel : ViewModel
	{
		#region コマンド: OpenFolderBrowserCommand
		private ViewModelCommand _OpenFolderBrowserCommand;
		public ViewModelCommand OpenFolderBrowserCommand => _OpenFolderBrowserCommand ?? (_OpenFolderBrowserCommand = new ViewModelCommand(OpenFolderBrowser, CanOpenFolderBrowser));
		public bool CanOpenFolderBrowser() => true;
		public void OpenFolderBrowser()
		{
			if (!CanOpenFolderBrowser()) return;

			var message = new FolderSelectionMessage("show_selectfolderdialog") {
				Title = "Save image files",
			};

			Messenger.Raise(message);
			if (string.IsNullOrWhiteSpace(message.Response)) {
				return;
			}

			var folderPath = message.Response;
			Debug.WriteLine(folderPath);
		}
		#endregion
	}
}

Exception occurred here

    public class FolderBrowserDialogInteractionMessageAction : InteractionMessageAction<FrameworkElement>
    {
        protected override void InvokeAction(InteractionMessage m)
        {
            if (m is FolderSelectionMessage folderSelectionMessage)
            {
                var hostWindow = Window.GetWindow(AssociatedObject ?? throw new InvalidOperationException());
                if (hostWindow == null) return;

                using (var dialog = FolderSelectionDialogFactory.CreateDialog(folderSelectionMessage.DialogPreference))
                {
                    if (dialog == null) throw new InvalidOperationException();

                    dialog.Title = folderSelectionMessage.Title;
                    dialog.Description = folderSelectionMessage.Description;
                    dialog.SelectedPath = folderSelectionMessage.SelectedPath;
                    dialog.Multiselect = folderSelectionMessage.Multiselect;

                    if (dialog.ShowDialog(hostWindow).GetValueOrDefault())
                    {
                        // V3.2.3.2 code -> InvalidOperationException
--->                    folderSelectionMessage.SelectedPaths = dialog.SelectedPaths;
                        folderSelectionMessage.Response = folderSelectionMessage.SelectedPaths.FirstOrDefault();

                        // V2.2.0 code -> No exception
                        //folderSelectionMessage.Response = dialog.SelectedPath;
                    } else
                    {
                        folderSelectionMessage.Response = null;
                    }
                }
            }
        }
    }

#いつもLivetを愛用しています。runceelさんメンテナンスありがとうございます。

@leon-joel leon-joel changed the title FolderSelectionMessage cause InvalidOperationExceptionin ver 3.2.3.2 FolderSelectionMessage cause InvalidOperationException in ver 3.2.3.2 Oct 12, 2021
@runceel runceel self-assigned this Oct 12, 2021
@runceel
Copy link
Owner

runceel commented Oct 14, 2021

@leon-joel
SelectedPaths プロパティが依存関係プロパティになっているためこの例外が起きているようです。
SelectedPaths プロパティを普通のプロパティにすれば、例外は起きなくなるのですが弊害として SelectedPaths のバインディングが出来なくなります。

個人的な感覚では SelectedPaths は出力用のプロパティなのでバインディングは特に必要無いと思うのですがどう思いますか?

該当プロパティは最近新設されたもので、これまではなかったものなので、問題なさそうなら普通のプロパティにして対応しようと思います。

@leon-joel
Copy link
Author

leon-joel commented Oct 14, 2021

@runceel

個人的な感覚では SelectedPaths は出力用のプロパティなのでバインディングは特に必要無いと思うのですがどう思いますか?

はい。入力側はバインディングできる必要はないと思います。
Livet内部で使用しているCommonOpenFileDialogも SelectedPaths を受け入れる方法がないですし。

該当プロパティは最近新設されたもので、これまではなかったものなので、問題なさそうなら普通のプロパティにして対応しようと思います。

はい、了解しました。

@runceel
Copy link
Owner

runceel commented Oct 16, 2021

@leon-joel
FolderSelectionMessageResponse プロパティを string から string[] にして SelectedPaths を削除しました。
他のファイル選択系のメッセージと仕様を合わせる形にしました。

ですので破壊的変更になってしまいました。

v4.0.0 (.NET 6 SDK RC2 でビルドしてるので 11 月の .NET 6 リリース後再ビルドを行う予定です) としてリリースしました。

@leon-joel
Copy link
Author

v4.0.0確認しました。
ありがとうございました。

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants