我正在使用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>
答案 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。