MVVM + WPF + Popup =无能为力

时间:2010-01-04 06:54:36

标签: wpf mvvm popup

我仍在努力将我现有的WPF应用程序修改为与MVVM方法“兼容”。我越来越近了,但我不确定如何解决剩下的几个障碍。

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

为了解决这个问题,我认为这是我应该采取的方向,但我希望能为您提供任何额外的输入。 :)

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

    <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>
    
  2. 通过触发器弹出弹出窗口,例如

                            <Button.Triggers>
                                <Trigger Property="Button.IsMouseOver" Value="True">
                                    <Setter TargetName="MyPopup" Property="IsOpen" Value="True" />
                                </Trigger>
                            </Button.Triggers>
    
  3. 认为#1没问题,但我正在努力争取#2。这是解决问题的正确方法吗?如果是这样,将Popup的IsOpen属性设置为True的正确XAML语法是什么?我找不到这方面的例子。

    如果我的整个想法都存在缺陷,我很想知道我的其他选择是什么。谢谢!

1 个答案:

答案 0 :(得分:19)

这是我要做的,首先我将可重用的部分分成资源,然后在XAML中使用ContentControls引用它们。这适用于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>

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>

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

<ContentControl Template="{StaticResource MyControlTemplate}">
    <Button Content="Test"/>
</ContentControl>

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