[이 문제를 진단하는 첫 번째 찌르기에서 잘못된 질문을했습니다. 이제 수정되었습니다.]Caliburn Micro Conductor.OneActive를 사용할 때 블렌드 상호 작용 이벤트 트리거가 여러 번 실행되는 이유는 무엇입니까?
Conductor.Collection.OneActive에서 상속하는 하나의 주 창이있는 WPF 응용 프로그램이 있습니다. 탐색 요청을 처리하고 상태가 유지되도록보기 모델의 캐시를 유지합니다. 이 비공개 컬렉션은 base.Items 컬렉션과 거의 동일하지만 모든 뷰 모델이 IScreen이 아닙니다.
모든 항목이 올바르게 작동하고 하나의 활성 항목에서 다른 항목으로 이동할 때 상태가 유지됩니다. 그러나 상호 작용 트리거에 버그가 있습니다. 활성 항목이 IScreen 인 경우 트리거는 매번 다시 연결되는 것처럼 탐색 당 추가 시간을 실행합니다. 일반 트리거는이 작업을 수행하지 않고 상호 작용 라이브러리의 작업 만 트리거합니다. 활성 항목이 PropertyChangedBase에서 상속받은 IScreen이 아닌 경우이 문제는 보이지 않지만 탐색 중에는 뷰의 상태를 잃게됩니다.
보기로 네 번 이동하면 해당 이벤트는 네 번, 다섯 번, 다섯 번씩 실행됩니다.
이것은 동일한 as this question처럼 보이지만 특정 viewmodels이 무엇인지 알지 못하기 때문에 그의 솔루션을 사용할 수 없으며 공개 속성을 만들 수 없습니다.
내 메인 윈도우 클래스는 다음과 같습니다
public sealed class MainWindowViewModel : Conductor<object>.Collection.OneActive, IHandle<NavigateToUriMessage>
{
public void Handle(NavigateToUriMessage message)
{
var ignoredUris = RibbonUri.GetItems().Where(t => t.SubTabs.Count > 0).Select(t => t.Uri);
Func<string, bool> isMatch = uri => uri == message.Uri;
if (isMatch(RibbonUri.BookkeepingBatchView.Uri))
GetAndActivateViewModel<BatchPanelViewModel>(message);
...
}
private T GetAndActivateViewModel<T>(NavigateToUriMessage message) where T : class
{
var vm = GetViewModel<T>(message.Uri);
ActivateItem(vm);
return (T) vm;
}
private object GetViewModel<T>(string uri) where T : class
{
if (viewModelCache.ContainsKey(uri))
return viewModelCache[uri];
var vm = viewModelFactory.Create<T>();
viewModelCache.Add(uri, vm);
return vm;
}
}
내 MainWindow를 XAML은 다음과 같습니다 : 활성 항목보기에서
<Window x:Class="Ui.Views.MainWindowView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
d:DataContext="{d:DesignInstance Type=viewModels:MainWindowViewModel, IsDesignTimeCreatable=False}"
mc:Ignorable="d"
WindowState="Maximized" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="1"/>
<RowDefinition/>
<RowDefinition Height="1"/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<ContentControl x:Name="MainRibbon" Grid.Row="0" Margin="0" />
<Grid Background="#FFBBBBBB" Grid.Row="1" />
<ContentControl Grid.Row="2" x:Name="ActiveItem" Background="White" />
<Grid Grid.Row="3" Background="#FFBBBBBB"/>
<ContentControl x:Name="BottomStatusBar" Grid.Row="4"/>
</Grid>
</Window>
그리고 XAML은 다음과 같습니다
<DataGrid Focusable="True" FocusVisualStyle="{x:Null}" SelectionMode="Single" HeadersVisibility="None" IsReadOnly="True" GridLinesVisibility="None" AutoGenerateColumns="False" Background="Transparent" BorderThickness="0" Grid.Row="3" Grid.RowSpan="2">
<i:Interaction.Triggers>
<ei:KeyTrigger Key="Left" FiredOn="KeyUp" ActiveOnFocus="True" >
<cal:ActionMessage MethodName="TryCollapseSelectedItem"/>
</ei:KeyTrigger>
<ei:KeyTrigger Key="Right" FiredOn="KeyUp" ActiveOnFocus="True" >
<cal:ActionMessage MethodName="TryExpandSelectedItem"/>
</ei:KeyTrigger>
</i:Interaction.Triggers>
....
을 : http://stackoverflow.com/a/8835349/81317 ActiveItem이 설정되면 자식 컨트롤 Loaded 이벤트가 발생합니다. KeyTrigger는 Load에 연결되어 있으므로 여러 번로드됩니다. 자체 KeyTrigger 클래스를 만들고 KeyTrigger에서 상속하면 OnEvent 메서드를 재정의하고 여러 첨부 파일을 중지 할 수 있습니다. 그러나 ActivateItem을 수행 할 때마다 Load 이벤트가 얼마나 많은 영향을 받는지 궁금합니다. 잘못된 일을하고 있거나 KeyTrigger에 문제가있어 회피 할 수 없습니다. –
디 컴파일러를 사용하여 추가 조사를 수행하면 KeyTrigger가 Load 중에 키 누르기 이벤트 처리기를 연결하지만 UserControl이 언로드 될 때 OnDetaching 호출이 발생하지 않으므로 대칭이 아니어야합니다. 따라서 UserControl은 활성화 될 때마다 Load 이벤트를 가져오고 KeyTrigger는 유선 상태입니다. –