MVVM + WPF + Popup =无能为力

Dav*_*ave 21 wpf popup mvvm

我仍在努力将我现有的WPF应用程序修改为与MVVM方法"兼容".我已经非常接近,但我不确定如何解决剩下的几个障碍之一.

我有一个GUI元素(当前是一个按钮,虽然它可能是一个标签),当鼠标进入它时,它会触发MouseEnter事件,这会在代码隐藏中创建一个弹出窗口.弹出窗口由一个带有几个按钮的简单堆栈面板布局组成.每个按钮的Click事件当前都被分配给相同的事件处理程序,除了我更改Tag属性以执行简单(俗气)命令参数.我正在用MVVM中的"正确"方式进行摔跤,因为我现在这样做的方式非常难看.

为了解决这个问题,我认为这是我应该采取的方向,但我会感谢您提供给我的任何其他输入.:)

  1. 在XAML中创建弹出窗口.由于我的Popup内容是静态的,我应该能够完全在XAML中创建Popup.此外,每个按钮都将绑定到同一个ICommand派生类.例如

    <Popup x:Key="MyPopup" StaysOpen="False" Placement="Right">
        <Border Background="White" BorderBrush="Black" Padding="5" BorderThickness="2" CornerRadius="5">
            <StackPanel Orientation="Vertical">
                <Button Command="{Binding MyCommand}" CommandParameter="5">5</Button>
                <Button Command="{Binding MyCommand}" CommandParameter="10">10</Button>
                <Button Command="{Binding MyCommand}" CommandParameter="15">15</Button>
                <Button Command="{Binding MyCommand}" CommandParameter="20">20</Button>
            </StackPanel>
        </Border>
    </Popup>
    
    Run Code Online (Sandbox Code Playgroud)
  2. 通过触发器弹出弹出窗口,例如

                            <Button.Triggers>
                                <Trigger Property="Button.IsMouseOver" Value="True">
                                    <Setter TargetName="MyPopup" Property="IsOpen" Value="True" />
                                </Trigger>
                            </Button.Triggers>
    
    Run Code Online (Sandbox Code Playgroud)

认为#1还可以,但我正在努力#2.这是解决问题的正确方法吗?如果是这样,将Popup的IsOpen属性设置为True的正确XAML语法是什么?我找不到这方面的例子.

如果我的整个想法都有缺陷,我很乐意听到我的其他选择.谢谢!

Avi*_* P. 19

这就是我要做的,首先我将可重用的部分分成资源,然后ContentControls在XAML中引用它们.这适用于Popup以及Button.但是我不想限制自己只使用一个按钮,所以我也会使用一个按钮ContentControl:

弹出模板:

<ControlTemplate x:Key="PopupTemplate">
    <Border 
                Background="White" 
                BorderBrush="Black" 
                Padding="5" 
                BorderThickness="2" 
                CornerRadius="5">
        <StackPanel Orientation="Vertical">
            <Button Command="{Binding MyCommand}" 
                            CommandParameter="5">5</Button>
            <Button Command="{Binding MyCommand}" 
                            CommandParameter="10">10</Button>
            <Button Command="{Binding MyCommand}" 
                            CommandParameter="15">15</Button>
            <Button Command="{Binding MyCommand}" 
                            CommandParameter="20">20</Button>
        </StackPanel>
    </Border>
</ControlTemplate>
Run Code Online (Sandbox Code Playgroud)

ContentControl模板:

<ControlTemplate x:Key="MyControlTemplate" TargetType="ContentControl">
    <Grid Name="MyControl">
        <ContentPresenter Content="{TemplateBinding Content}"/>
        <Popup Name="MyPopup" StaysOpen="True" Placement="Bottom">
            <ContentControl Template="{StaticResource PopupTemplate}"/>
        </Popup>
    </Grid>
    <ControlTemplate.Triggers>
        <Trigger SourceName="MyControl" 
                 Property="UIElement.IsMouseOver" 
                 Value="True">
            <Setter TargetName="MyPopup" 
                    Property="Popup.IsOpen" 
                    Value="True"/>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>
Run Code Online (Sandbox Code Playgroud)

现在在主窗口XAML中,我将创建以下内容:

<ContentControl Template="{StaticResource MyControlTemplate}">
    <Button Content="Test"/>
</ContentControl>
Run Code Online (Sandbox Code Playgroud)

如果您有任何疑问,我将很乐意回答.