如何为Caliburn Micro附加GridViewColumnHeader.Click的eventHandler?

时间:2015-05-21 09:13:52

标签: wpf events caliburn.micro attached-properties

我有一个带有GridView的ListView作为视图,它按惯例绑定到我的ViewModel的Instances属性:

<ListView Name="Instances">
  <ListView.View>
    <GridView>
      <GridViewColumn DisplayMemberBinding="{Binding Property}"
                      Header="Property"/>
    </GridView>
  </ListView.View>
</ListView>

现在,当我点击GridViewColumnHeader时,我需要在ViewModel上触发一些方法。

我尝试过像这样增强GridViewColumn

<ListView Name="Instances"
          cal:Message.Attach="[Event GridViewColumnHeader.Click] = [Action Foo()]">
  <!-- the rest stays unchanged -->
</ListView>

我甚至尝试使用ColumnHeaderContainerStyle,如此

<GridView>
  <GridView.ColumnHeaderContainerStyle>
    <Style TargetType="GridViewColumnHeader">
      <EventSetter Event="Click">
        <cal:ActionMessage MethodName="Foo"/>
        <!-- does not compile -->
      </EventSetter>
    </Style>
  </GridView.ColumnHeaderContainerStyle>
</GridView>

这显然不起作用。

如何使用Caliburn Micro将ViewModel中的方法(而不是带绑定的命令)连接到附加事件(以更一般的方式询问)?

2 个答案:

答案 0 :(得分:1)

我已按照@XAMIMAX建议解决了这个问题:

<GridView.ColumnHeaderTemplate>
  <DataTemplate>
    <Button Content="{Binding}"
            BorderBrush="Transparent"
            Background="Transparent"
            cal:Message.Attach="[Event Click] = [Action Foo($this)]">
      <Button.Template>
        <ControlTemplate TargetType="Button">
          <ContentPresenter />
        </ControlTemplate>
      </Button.Template>
    </Button>
  </DataTemplate>
</GridView.ColumnHeaderTemplate>

这会触发ViewModel上的Foo并将{Binding}(在我的情况下:property-name)传递给它。

答案 1 :(得分:1)

我找到this文章解释了一点点校准,我以前从未使用过校准器,所以我不得不做一些研究。
这就是本文在另一种方法中提出Binding的方式。

<TextBox x:Name="Name" />
<Button Content="Save"> 
    <i:Interaction.Triggers> 
        <i:EventTrigger EventName="Click"> 
            <cal:ActionMessage MethodName="Save"> 
               <cal:Parameter Value="{Binding ElementName=Name, Path=Text}" /> 
            </cal:ActionMessage> 
        </i:EventTrigger> 
    </i:Interaction.Triggers> 
</Button> 

其中:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
xmlns:cal="http://www.caliburnproject.org"

为了让您继续在应用程序中使用TextBlock,您必须创建GridViewColumnHeader的明确定义,如下所示:

<DataTemplate>
<!-- Without the Calibrum micro -->
    <TextBlock Text="Test">
       <TextBlock.InputBindings>
          <MouseBinding MouseAction="LeftClick" Command="{Binding TestCommand}" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=TextBlock}, Path=Text}"/>
       </TextBlock.InputBindings>
    </TextBlock>
<!-- With Calibrum Micro -->
    <TextBlock>
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="LeftClick">
                <cal:ActionMessage MethodName="Save">
                    <cal:Parameter Value="{Binding ElementName=Name, Path=Text}" /> 
                </cal:ActionMessage> 
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </TextBlock>
</DataTemplate>

现在这只是基于我可以从互联网收集的材料,我无法在工作时对其进行测试。
然而,如果不能正常工作,应该让您了解如何克服开发中的一些困难 编辑:
并回答你的问题:
GridViewColumnHeader Template替换为DataTemplate的明确定义并使用按钮以便您可以附加到Click事件,或者您也可以使用TextBlock这个例子可以避免使用Button带来不必要的开销 的修改
在做了一些研究后,我可以得出结论,在View模型上使用这些方法可以轻松有趣:-) 看看我的工作ListView:

<ListView>
<ListView.View>
    <GridView>
        <GridView.ColumnHeaderTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding}">
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="MouseDown">
                            <ei:CallMethodAction MethodName="TestPublicMethod" TargetObject="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext}"/>
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </TextBlock>
            </DataTemplate>
        </GridView.ColumnHeaderTemplate>
        <GridViewColumn Header="Example Header"/>
    </GridView>
</ListView.View>
<ListViewItem>
    <StackPanel Orientation="Horizontal">
        <TextBlock>
            normal text with a lot of characters
        </TextBlock>
        <Rectangle Width="20" Height="20" Fill="Red"/>
    </StackPanel>
</ListViewItem>

视图模型(消息是INPC的属性):

#region Public Methods

public void TestPublicMethod() {     Message = "You have just invoked a public method !!!."; }

#endregion
地点:

xmlns:ei="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"  

抱歉格式不佳,但编辑不想在星期一早上工作:-p。
因为TextBlock将只使用所需的最小空间,所以可以使用这个脏技巧使其伸展到列标题的宽度:

Width="{Binding RelativeSource={RelativeSource AncestorType=GridViewColumnHeader}, Path=ActualWidth}"