Как привязать данные Нажмите = для функции на объекте, а не на странице - PullRequest
2 голосов
/ 11 июля 2010

Я использую Silverlight, но меня также заинтересовал бы ответ WPF

У меня есть список, связанный данными со связанным списком «Избранное». Каждый фаворит содержит имя и номер телефона.

Список привязан к DataTemplate, который описывает графические аспекты. В этом шаблоне есть кнопка - Dial. Когда вы нажимаете на эту кнопку, я хочу, чтобы вызывался метод Dial () элемента Favorite. Прямо сейчас вызывается метод Dial страницы / окна.

Если это невозможно, могу ли я как-нибудь привязать Фаворита к кнопке? такой, что я знаю, какой Фаворит был связан с нажатием кнопки?

приведенный ниже XAML не работает, Text = "{Binding Name}" отлично работает, поскольку он привязывается к свойству Name в избранном, но Click = "{Binding Dial}" не вызывает 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 ]

3 голосов
/ 11 июля 2010

Так и должно быть:

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

Тогда вы получите объект данных в качестве параметра команды.В этом сценарии вы должны предоставить свойство, которое называется Dial и возвращает значение 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 голос
/ 11 июля 2010

Первое решение HappyClicker является лучшим для большинства целей, поскольку оно поддерживает хорошие шаблоны проектирования, такие как MVVM.

Есть еще один простой способ получить тот же результат, используя прикрепленное свойство, поэтому вы можете написать:

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

и метод Edit () будет вызываться для DataContext кнопки.

Вот как может быть реализован класс 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, которые он получил.

...