Caliburn.Micro指挥:触发/动作射击比exptected更多(Caliburn.Micr

2019-10-19 02:28发布

我试图把一个很简单的例子程序,但因为intented它不工作。

下面是这种情况:

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!)

ShellViewModel

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;
    }
}

ShellView

<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>

LoginView

<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>

LoginViewModel

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.

上面的例子只是做工精细,显示登录视图点击登录按钮后,在主显示主视图。

在登录查看有有一个事件触发一个文本框。 按Enter键后,它会调用视图模型从一个方法,并显示一个消息框。

问题:

当去掌握视图,并回到登录碰头输入 - 它显示两次在MessageBox!

要掌握和再次回来 - >将显示其3倍..等等。

我认为,触发应该触发一次。 如何才能实现这种行为?

Answer 1:

我想这是因为你做的每一次你加载它重新绑定的事件处理程序的视图的视图的ActivateItem。 尝试设置ActiveItem属性代替(其与x中的ContentControl中:名称=“ActiveItem”被绑定到)。 也可以尝试使用公共变量来保存您的视图模型:

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");
    }


文章来源: Caliburn.Micro Conductor: Trigger/Action firing more than exptected