我使用VS2013、Wpf 4.5和Caliburn Micro。我想使用矩形并将文本块放入其中。我在StackOverflow中找到了一个解决方案:将矩形和文本块放入网格中。它有效。
然后,如果用户点击矩形,我想捕捉点击事件。所以我在标记中添加了x:Name="ClickMe"属性,将点击事件绑定到视图模型。它可以工作,但前提是鼠标指向矩形的非文本区域只要鼠标指针位于TextBlock区域,单击事件就会被忽略
我的第一个尝试是:使用x:Name="ClickText1"将TextBlock绑定到事件处理程序ClickText1()。它不起作用。TextBlock似乎没有Click事件。
我的第二次尝试:我尝试将TextBlock放在StackPanel中,使用x:Name="ClickStack"绑定StackPanel,事件处理程序ClickStack()将调用ClickMe()。它不起作用,因为ClickStack()在应用程序启动后立即被调用,并且在视图显示前被调用。所以我的尝试失败了!
我想要的是:无论文本区域还是非文本区域,整个矩形区域都应该是可点击的(并引发点击事件),并且点击事件可以绑定到视图模型中的一个事件处理程序。所有的工作都应该在校准微模式,没有代码落后。
我在下面附上我的示例代码。请随意修改它,并向我展示如何解决它。你也可以建议我其他简单的方法,在不使用网格的情况下将文本放在矩形上。但是,由于我的项目的要求,请不要建议我使用按钮控件。提前谢谢。
视图:
<UserControl x:Class="CMWpfShapeWithCaption.Views.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cm="http://www.caliburnproject.org"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="300"
d:DesignWidth="300"
mc:Ignorable="d">
<Grid Width="300"
Height="300"
ShowGridLines="False">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20*" />
<ColumnDefinition Width="20*" />
<ColumnDefinition Width="20*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20*" />
<RowDefinition Height="20*" />
<RowDefinition Height="20*" />
</Grid.RowDefinitions>
<Rectangle x:Name="ClickMe"
Grid.Row="1"
Grid.Column="1"
Fill="Aqua" />
<StackPanel Grid.Row="1"
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<TextBlock x:Name="ClickText1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
cm:Message.Attach="[Event MouseLeftButtonDown] = [Action ClickMe()]"
Text="{Binding Path=Text1}"
TextWrapping="Wrap" />
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center"
cm:Message.Attach="[Event MouseLeftButtonDown] = [Action ClickMe()]"
Text="{Binding Path=Text2}"
TextWrapping="Wrap" />
</StackPanel>
</Grid>
</UserControl>
视图模型:
using System;
using System.Windows;
using Caliburn.Micro;
namespace CMWpfShapeWithCaption.ViewModels
{
public class ShellViewModel : PropertyChangedBase
{
public ShellViewModel()
{
Text1 = "Text1";
Text2 = "Text2";
}
public String Text1 { get; set; }
public String Text2 { get; set; }
// Problem: this will be called only if Mouse points non-text area of grid
// Target: This should be called regardless non-text or text-area,
// as long as the mouse is clicked within rectangle area.
public void ClickMe()
{
MessageBox.Show("Panel is clicked");
}
// This trick doesn't work at all.
// It seems TextBlock has no click event?
public void ClickText1()
{
ClickMe();
}
}
}
编辑:
加入xaml:
xmlns:cm="http://www.caliburnproject.org"
cm:Message.Attach="[Event Tapped]=[Action ClickMe()]"
它仍然不能像我想要的那样工作。
编辑(最终):
我使用鼠标左键向下而不是Tapped,它现在可以工作了。
Tapped是您必须针对的事件,因为Click不存在,因此控件和约定将不起作用。cm:Message.Attach="[Event Tapped] = [Action ClickMe()]"
是您唯一的选择。你可以强制一个约定,但这将是该控件的自定义。