将事件绑定到ItemsControl中的按钮 [英] Binding events to buttons in an ItemsControl

查看:306
本文介绍了将事件绑定到ItemsControl中的按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Windows Phone 7应用程序,一些xaml看起来像:

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

这里的项目模板如下所示:

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

最后,MyInner_Item模板看起来像:

 < DataTemplate x:Key =MyInner_Item> 
< Button x:Name =MyButton>
< Button.Template>
< ControlTemplate>
< Border Horizo​​ntalAlignment =CenterVerticalAlignment =Centerx: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事件添加一个事件处理程序。 / p>

这是catch:后面的代码写在F#中。据我所知,我不能在XAML中指定我的事件处理程序,因为F#不以任何好的方式与WPF通信。所以我需要在代码中手动添加我的事件处理程序。



有没有一个简单的方法?



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

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

这里,BoardData是列表列表。



我想知道是否可以循环通过ItemsControl中的控件来添加我的事件处理程序?我有一些麻烦这样做。例如,在以下内容中:

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

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



那么,我该怎么去附加事件处理程序,以便我可以回应按钮被点击?

解决方案

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


另外,请注意,当您在 ItemsControl 控件中执行绑定表达式内(即ItemTemplate)项目时,可以绑定到什么属性的范围减少到当前项的属性。因此,ViewModel的所有属性都超出范围,除非完全指定即< Button Command = {Binding Source = ViewModel,Path = Property1.Property2.etc} /> 。让我知道这是否有帮助。


I have a windows phone 7 app with some xaml that looks like:

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

The item template here looks like:

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

And finally, the MyInner_Item template looks like:

<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>

So, it's an ItemsControl, which contains an ItemsControl, which contains buttons. This essentially creates a 2D array of buttons.

What I want to do is add an event handler to the Click event of the buttons.

Here's the catch: the code that sits behind this is written in F#. I can't, to the best of my knowledge, specify my event handler in the XAML, as F# doesn't talk to WPF in any nice way. So I need to add my event handler(s) manually in code.

Is there an easy way of doing this?

Currently, I have some F# which looks like:

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

Here, the BoardData is a list of lists.

I was wondering if it's possible to loop through the controls in the ItemsControl, to add my event handlers? I'm having a bit of trouble doing this though. For example, in the following:

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

...sets container to null. In fact, all the methods I've tried from myView.ItemContainerGenerator returns null.

So, how should I go about attaching my event handler, so that I can respond to the buttons being clicked?

解决方案

I have not done any Windows 7 Phone development, but I have done plenty of XAML + Silverlight development with C# and now I'm getting into doing some F# development. The approach I would take is by not using event handler's at all. Since you are using a button, make a class that derives from ICommand and add that type as a public property on your ViewModel so you could bind it to the Command property of the button. The benefits of using the ICommand interface over event handlers is that you could also have a condition on when the button is enabled to do the action.

Also, take notice that when you are doing binding expressions within (i.e. ItemTemplate) items in an ItemsControl control, the scope of what properties you can bind to are reduced to the properties of the current item. So all of the properties of the ViewModel are out of scope, unless you specify it fully i.e. <Button Command={Binding Source=ViewModel, Path=Property1.Property2.etc} />. Let me know if this helped.

这篇关于将事件绑定到ItemsControl中的按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆