将事件绑定到ItemsControl中的按钮

时间:2011-07-31 17:39:52

标签: xaml windows-phone-7 f# event-handling

我有一个带有一些xaml的Windows Phone 7应用程序,如下所示:

<Grid x:Name="ContentGrid" Grid.Row="1">
    <ItemsControl x:Name="MyView" ItemTemplate="{StaticResource MyInner}"/>
</Grid>

此处的项目模板如下所示:

<DataTemplate x:Key="MyInner">
    <ItemsControl ItemsSource="{Binding}" ItemTemplate="{StaticResource MyInner_Item}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
</DataTemplate>

最后,MyInner_Item模板如下所示:

<DataTemplate x:Key="MyInner_Item">
    <Button x:Name="MyButton">
        <Button.Template>
            <ControlTemplate>
                <Border HorizontalAlignment="Center" VerticalAlignment="Center" x:Name="myborder">

                    <Image Source="{Binding Path=ImageUri}" Width="{Binding Path=Width}" Height="{Binding Path=Height}" Stretch="Fill" />
                </Border>
            </ControlTemplate>
        </Button.Template>
    </Button>
</DataTemplate>

所以,它是一个ItemsControl,它包含一个ItemsControl,其中包含按钮。这基本上创建了一个2D按钮阵列。

我想要做的是为按钮的Click事件添加一个事件处理程序。

这就是问题:这背后的代码是用F#编写的。据我所知,我不能在XAML中指定我的事件处理程序,因为F#没有以任何好的方式与WPF对话。所以我需要在代码中手动添加我的事件处理程序。

有没有一种简单的方法可以做到这一点?

目前,我有一些F#看起来像:

let myView : ItemsControl = this?MyView
do myView.ItemsSource <- viewModel.BoardData 

这里,BoardData是一个列表列表。

我想知道是否可以遍历ItemsControl中的控件,添加我的事件处理程序?我这样做有点麻烦。例如,在以下内容中:

let container = myView.ItemContainerGenerator.ContainerFromItem(myView.Items.[0])

...将容器设置为null。实际上,我从myView.ItemContainerGenerator尝试的所有方法都返回null。

那么,我应该如何附加我的事件处理程序,以便我可以响应被点击的按钮?

1 个答案:

答案 0 :(得分:3)

我没有做任何Windows 7 Phone开发,但是我已经用C#做了大量的XAML + Silverlight开发,现在我开始做一些F#开发了。我将采取的方法是不使用事件处理程序。由于您使用的是按钮,因此请创建一个派生自ICommand的类,并将该类型作为公共属性添加到ViewModel上,以便将其绑定到按钮的Command属性。在事件处理程序上使用ICommand接口的好处是,您还可以了解启用按钮何时执行操作的条件。

另外,请注意,当您在ItemsControl控件中绑定表达式(即ItemTemplate)项时,您可以绑定到的属性的范围将缩减为属性当前项目。所以ViewModel的所有属性都超出了范围,除非你完全指定它,即<Button Command={Binding Source=ViewModel, Path=Property1.Property2.etc} />。如果这有帮助,请告诉我。