【问题标题】:MVVM Command without A Button没有按钮的 MVVM 命令
【发布时间】:2011-04-25 01:26:15
【问题描述】:

我想启动一个绑定命令,但我不想在我的UserControl 上使用Button。实际上UserControl 本身就是Button。当它在其表面上的任何位置单击时,我想启动一个绑定命令。有没有办法给UserControl 一个命令?

附带说明:一个控件的一个命令和几个特定的​​开箱即用控件?这一切似乎有点笨拙。我开始认为 MVVM 是不切实际的。我可以使用接口和 OOP 很好地解耦我的 UI。不管怎样,我还是有希望的。

另外,我不愿意破解任何东西或使用昂贵的解决方法。如果我不能做到这一点,我将放弃 MVVM。

【问题讨论】:

  • 如果您还不知道,您可以将任何类型的内容放入按钮中,而不仅仅是文本。只需将复杂控件 Content 的 XAML 放在 <Button.Content> 中。这为您提供了您需要的任何特殊内容,以及标准按钮的所有行为和样式。如果您想修改按钮本身的外观/感觉,超出属性样式可以实现的范围,请阅读更多关于控制模板的信息,它可以让您根据自己的喜好修改按钮的任何部分。 WPF 的库存控件如此之少的主要原因是控件本身更加灵活。
  • 我已经知道了。但是如何让它伸展以填充按钮?我想在按钮内使用网格。按钮不像面板那样工作,我必须给网格一个固定的宽度才能让它有任何尺寸。我想我可能能够将网格的宽度绑定到按钮的宽度。那可能行得通。谢谢,如果这不仅仅是评论,我会将您标记为已回答。 :D
  • 我发布了一个将网格正确缩放到按钮大小的示例。

标签: wpf user-controls mvvm command


【解决方案1】:

在此处查看 ICommandSource 接口:http://msdn.microsoft.com/en-us/library/system.windows.input.icommandsource.aspx。如果你想让一个控件有一个命令,那么你的控件应该实现这个接口。实现此接口的控件示例是 ButtonBase 和 MenuItem。希望这会有所帮助。

【讨论】:

  • 我只是对与后端的通信线路有限感到不满。来自 WinForms 丰富的事件驱动世界,很难习惯将狭窄的未定义管道返回到逻辑层。这个答案正是我想要的;一种无需使用愚蠢按钮即可创建自己的命令界面的方法!谢谢迈克尔。
【解决方案2】:

如果您的 UserControl 本质上是一个 Button,为什么要编写自己的 UserControl 而不是使用 Button 类?

要添加更多信息,请执行以下操作:

  1. 子类按钮,把你需要的任何额外的 DependencyProperties 放在那里 - 它应该是一个非常空的类(你甚至可以有类似 public class MyCoolButton : Button { } 的东西
  2. 添加一个 TargetType 为 MyCoolButton 的样式 - 不要命名该样式,以便它适用于所有 MyCoolButtons
  3. 覆盖样式的默认模板,然后粘贴到您的 Xaml 代码中。您可能需要在这里做一些工作来处理“正常/推送/禁用”状态。如果您使用的是 v4.0,则可以在此处使用 VSM。

【讨论】:

  • 这是一种解决方法。你们不明白。我知道如何“让它发挥作用”。我不希望它只是工作,我想喜欢它的工作方式,我只是不喜欢命令架构。关于 MVVM 的其他大部分内容我都喜欢,但这很笨拙。
  • @Jordan,命令的问题在于,只有当您有一个知道如何解释 CanExecute 并知道什么条件应该触发 Execute 的控件时,它们才有意义。如果要提供命令绑定的自定义解释,则需要实现适当的接口。值得庆幸的是,这种低级实现在 WPF 中不太常见,因为您通常可以为现有控件设置样式或模板以利用现有命令模式。
  • 这不是一种解决方法,这是执行此操作的正确方法。
【解决方案3】:

我会同意保罗·贝茨的观点。

我经常使用按钮作为顶部容器创建自己的 ListBoxItemContainerStyle,其中只有一个无属性的内容呈现器。这让我可以在没有 Windows chrome 的情况下使用按钮功能(如命令)。

将它放在 ListBoxItemContainerStyle 中也可以让我在单击它时不显示正常的虚线边框 (FocusVisualStyle={x:Null})。

您是否使用 Visual Studio 或 Expression Blend 来进行样式设置?

此外,一些 MVVM 框架提供了一个界面,用于向按钮以外的控件添加命令式功能。 Caliburn 有一个相当丰富的命令模式。但是,我不确定它是否允许在非按钮控件上绑定命令。

【讨论】:

  • 有帮助,但不完全是我想要的。我知道如何欺骗这样的风格。我不想使用按钮!我希望我的命令逻辑有意义,并且必须有一个愚蠢的按钮才能绑定到命令。感谢您的回答。 :)
【解决方案4】:

OP 要求提供一个示例,说明如何使用按钮控件,但内容正确填充整个按钮。您可以使用 ContentAlignment 属性执行此操作:

<Button HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
    <Button.Content>
        <Grid IsHitTestVisible="False">
            <Grid.RowDefinitions>
                <RowDefinition Height="30" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <TextBlock Grid.Row="0" Text="Row0" />
            <TextBlock Grid.Row="1" Text="Row1" />
        </Grid>
    </Button.Content>
</Button>

这将创建一个按钮,其中两个标签使用 Grid 控件隔开。我将 Grid 标记为关闭 HitTestVisible,因为您必须决定哪些控件应该像按钮一样交互,哪些应该像控件一样交互。例如,您可能有一个嵌入的 TextBox,您希望在不点击按钮的情况下点击它,在这种情况下,它应该具有 HitTestVisible=True。

【讨论】:

    【解决方案5】:

    WPF 支持图层和透明度:

    Panel.ZIndex
    

    您可以在高级透明层上创建任何支持命令的东西,您想要的大小,作为按钮。

    【讨论】:

    • 这就是我所说的 hack。
    • @Jordan,有趣的是,WPF 按钮的默认控件模板在其实现中使用透明分层。各个层的可见性是动画的,以提供诸如悬停和鼠标向下的效果。
    猜你喜欢
    • 2012-11-24
    • 2016-07-08
    • 1970-01-01
    • 2015-06-07
    • 2018-06-02
    • 2013-09-08
    • 1970-01-01
    • 2022-01-19
    相关资源
    最近更新 更多