我正在尝试整理一个非常简单的示例应用程序,但它并没有像预期的那样工作。
以下是该方案:
Caliburn.Micro,MVVM,Silverlight 5.0 - 来自https://caliburnmicro.codeplex.com/wikipage?title=Screens%2c%20Conductors%20and%20Composition&referringTitle=Documentation的简单导体示例(简单导航)
我刚刚整理了一个实例: https://db.tt/kTIjKvRx
-> hit enter in textbox (messagebox displays 1x)
-> go to master and go back to login
-> hit enter in textbox (messagebox displays 2x!)
public class ShellViewModel : Conductor<object> {
public ShellViewModel() {
ShowLogin();
}
public void ShowLogin() {
ActivateItem(new LoginViewModel());
}
public void ShowMaster() {
ActivateItem(new MasterViewModel());
}
}
与此相同的结果:
public class ShellViewModel : Conductor<object> {
public ShellViewModel() {
LoginModel = new LoginViewModel();
MasterModel = new MasterViewModel();
ShowLogin();
}
public LoginViewModel LoginModel { get; set; }
public MasterViewModel MasterModel { get; set; }
public void ShowLogin() {
ActiveItem = LoginViewModel;
}
public void ShowMaster() {
ActiveItem = MasterViewModel;
}
}
<UserControl
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"
mc:Ignorable="d" x:Class="Hele.ShellView"
d:DesignWidth="438" d:DesignHeight="200">
<Grid>
<StackPanel Orientation="Vertical" HorizontalAlignment="Left" VerticalAlignment="Top">
<Button x:Name="ShowLogin" Width="100" Height="30" Content="Login"/>
<Button x:Name="ShowMaster" Width="100" Height="30" Content="Master"/>
<ContentControl x:Name="ActiveItem" " />
</Grid>
</UserControl>
<UserControl ... >
<Grid x:Name="LayoutRoot">
<StackPanel>
<TextBlock>Login</TextBlock>
<TextBox x:Name="Message" Text="{Binding Message, Mode=TwoWay}" >
<i:Interaction.Triggers>
<iex:KeyTrigger Key="Enter">
<cal:ActionMessage MethodName="Login" />
</iex:KeyTrigger>
</i:Interaction.Triggers>
</TextBox>
</StackPanel>
</Grid>
</UserControl>
public class LoginViewModel : Screen
{
public string Message { get; set; }
public void Login()
{
MessageBox.Show("login messagebox");
}
}
MasterView and MasterViewModel are just empty, nothing interesting there.
上面的例子工作正常,点击登录按钮显示登录视图后,在Master显示主视图。
在登录视图中,有一个具有事件触发器的文本框。点击Enter键后,它会从viewmodel调用一个方法并显示一个消息框。
当进入主视图并返回登录结束时按Enter键 - 它会显示消息框两次!
掌握并再次回来 - &gt;它将显示3x ..等等。
我认为触发器只能触发一次。我们怎样才能实现这种行为?
答案 0 :(得分:0)
我认为这是因为每次加载视图时都会执行ActivateItem,这会将事件处理程序重新绑定到视图。尝试设置ActiveItem属性(具有x:Name =“ActiveItem”的ContentControl绑定到该属性)。还可以尝试使用公共变量来保存视图模型:
public class ShellViewModel : Conductor<object> {
public ShellViewModel() {
ShowLogin();
}
public LoginViewModel { get; set; }
public MasterViewModel { get; set; }
public void ShowLogin() {
ActiveItem = LoginViewModel;
}
public void ShowMaster() {
ActiveItem = MasterViewModel;
}
}
修改强> 的
我能够重现这一点,这似乎是表达式交互的一个问题。如果我使用附加到按键的常规EventTrigger,它可以正常工作:
<TextBox Width="50" Text="{Binding Message, Mode=TwoWay}" >
<i:Interaction.Triggers>
<!--<iex:KeyTrigger Key="Enter">
<cm:ActionMessage MethodName="Page1KeyPress" />
</iex:KeyTrigger>-->
<i:EventTrigger EventName="KeyDown">
<cm:ActionMessage MethodName="Page1KeyPress" >
<cm:Parameter Value="$source" />
<cm:Parameter Value="$eventArgs" />
</cm:ActionMessage>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
public void Page1KeyPress(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
MessageBox.Show("Page 1 Key Press");
}