如何数据绑定Click =到对象上的函数而不是页面

时间:2010-07-10 21:15:12

标签: wpf silverlight data-binding

我正在使用Silverlight,但我也对WPF的答案感兴趣

我有一个数据绑定到“收藏夹”链接列表的列表。每个收藏夹都包含姓名和电话号码。

该列表绑定到描述图形方面的DataTemplate。在这个模板中是一个按钮 - 拨号。单击该按钮时,我希望调用Favorite的Dial()方法。现在调用页面/窗口的Dial方法。

如果这是不可能的,有没有办法让收藏夹以某种方式附加到Button?这样我知道哪个收藏夹与按钮有关?

以下XAML不起作用,Text =“{Binding Name}”效果很好,因为它绑定到收藏夹上的Name属性,但Click =“{Binding Dial}”不会调用Favorite上的Dial()。

    <DataTemplate x:Key="DataTemplate1">
        <StackPanel d:DesignWidth="633" Orientation="Horizontal" Height="93">
            <Button x:Name="DialButton" Content="Edit" Click="{Binding Dial}"/>
            <TextBlock x:Name="TextBlock" TextWrapping="Wrap" Text="{Binding Name}" FontSize="64" Height="Auto" FontFamily="Segoe WP SemiLight"/>                                      
        </StackPanel>
    </DataTemplate>

2 个答案:

答案 0 :(得分:3)

所以它应该去:

<Button CommandParameter="{Binding}" Command="{Binding Dial}"/>

然后您将收到数据对象作为命令参数。在此方案中,您必须提供名为Dial的Property并返回ICommand - 实现。如果属性在数据对象上不可用,但在主类(代码隐藏)上,则必须在绑定中查找,使用RelativeSource关键字。


另一种方法是制作点击处理程序。在单击处理程序中,您可以将发送方转换为Button(或FrameworkElement),然后从DataContext获取数据对象。我假设你试图创建这样一个解决方案。

private void Button_Click(object sender, RoutedEventArgs e) {
    Button btn = (Button)sender;
    MyObject obj = btn.DataContext as MyObject; 
    if(null != obj){
         obj.Dial();
         // or Dial(obj);
    }
}

标记必须如下:

<Button x:Name="DialButton" Content="Edit" Click="Button_Click"/> 

主要区别在于,我从Click-Event中删除了绑定并注册了一个事件处理程序。


第三种解决方案是在Button.ClickEvent的代码中注册处理程序。原理与第二个例子类似。

我不太了解silverlight。也许还有其他一些东西。

答案 1 :(得分:1)

HappyClicker的第一个解决方案是大多数用途的最佳解决方案,因为它支持良好的设计模式,如MVVM。

使用附加属性可以获得相同结果的另一种简单方法,因此您可以编写:

<Button Content="Edit" my:RouteToContext.Click="Edit" />

并且将在按钮的DataContext上调用Edit()方法。

以下是如何实现RouteToContext类:

  public class RouteToContext : DependencyObject
  {
    public static string GetClick(FrameworkElement element) { return (string)element.GetValue(ClickProperty); }
    public static void SetClick(FrameworkElement element, string value) { element.SetValue(ClickProperty, value); }
    public static DependencyProperty ClickProperty = ConstructEventProperty("Click");

    // Additional proprties can be defined here

    private static DependencyProperty ConstructEventProperty(string propertyName)
    {
      return DependencyProperty.RegisterAttached(
        propertyName, typeof(string), typeof(RouteToContext),
        new PropertyMetadata
        {
          PropertyChangedCallback = (obj, propertyChangeArgs) =>
            obj.GetType().GetEvent(propertyName)
              .AddEventHandler(obj, new RoutedEventHandler((sender, eventArgs) =>
                ((FrameworkElement)sender).DataContext
                  .GetType().GetMethod((string)propertyChangeArgs.NewValue)
                  .Invoke(((FrameworkElement)sender).DataContext,
                    new object[] { sender, eventArgs }
                  )
              ))
        }
      );
    }
  }

工作原理:设置RouteToContext.Click附加属性后,Type.GetEvent()用于查找名为“Click”的事件,并添加事件处理程序。此事件处理程序使用Type.GetMethod()在DataContext上查找指定的方法,然后调用DataContext上的方法,传递它收到的相同发送方和eventArgs。