Привязать метод к контролю xaml - PullRequest
3 голосов
/ 18 января 2012

Мне нужно привязать метод к пользовательскому элементу управления в файле xaml, а НЕ к результату метода.

Обычно пользовательский элемент управления запускает метод несколько раз при совпадении определенных условий.

Как я могу это сделать?

Я нашел некоторые решения в Интернете, но большинство из них связывают результат метода с xaml, а это не решение, которое я ищу.

Большое спасибо.

Ответы [ 4 ]

2 голосов
/ 19 января 2012

Нашел этот замечательный ответ:

Привязка статического метода / функции к свойству Func в XAML

Симон Расмуссен уже показывает все, что мне нужно в своем вопросепример кода.

2 голосов
/ 18 января 2012

Существует два различных подхода, которые вы можете использовать:

  • Команды , предоставляют свойство типа ICommand, которое вы связываете со свойствами Command элементов вашего пользовательского интерфейса.
  • Использование поведений для привязки события пользовательского интерфейса к методу в модели представления, например использование MVVM Light EventToCommandBehaviour .
1 голос
/ 18 января 2012

Не могли бы вы более конкретно указать, на каких условиях?@ColineE и @ChrisBD правильно указывают на то, что ICommands и EventTocommandBehavior помогут во многих обстоятельствах, таких как преобразование события нажатия кнопки мыши или события наведения мыши в вызов метода в ViewModel. Я бы рекомендовал использовать эти подходы, если они могут быть использованы, поскольку они считаются наилучшей практикой

Однако в некоторых случаях требуется нечто более сложное, чем это.Одним из решений является использование кода для приведения DataContext к типу модели представления и непосредственного вызова метода.Например:

// Inside MyViewModel.cs 
public class MyViewModel : INotifyPropertyChanged 
{ 
    // ... 
} 

// ...  
// Inside MyControl.xaml.cs 
public class MyControl : UserControl 
{ 
    public MyControl()  
    { 
        InitializeComponent();  
    } 

    pubilc void OnSomeConditionMatches() 
    { 
         var myViewModel = DataContext as MyViewModel; 
         if (myViewModel != null)  
         { 
              // Hacky, but it works
              myViewModel.CallCustomMethod();  
         }
    } 
}

Это считается немного хакерским и загрязняет программный код знанием типа ViewModel во время выполнения.Что-то, чего мы хотим избежать, поскольку это нарушает разделение интересов между View и ViewModel.

Другой метод - это то, что я использовал сам, когда имел дело с пользовательским элементом управления, который почти не поддерживает привязку данных.Используя интерфейс для представления и присоединенное свойство, вы можете внедрить экземпляр представления в viewModel и манипулировать им напрямую .Вроде гибридного паттерна MVVM / MVP, который я придумал MiVVM.

UML

MiVVM UML Diagram

Xaml:

<!-- Assumes myViewModel is the viewmodel we are binding to --> 
<!-- which has property InjectedUserControl of type IMyControl --> 
<Example3:MyControl DataContext="{StaticResource myViewModel}" 
                    Injector.InjectThisInto="InjectedUserControl"> 
</Example3:MyControl>

Код:

// Defines an interface to the usercontrol to  
// manipulate directly from ViewModel 
public interface IMyControl 
{ 
    // Our test method to call  
    void CallView(string message); 
} 

// Defines the usercontrol  
public partial class MyControl : UserControl, IMyControl 
{ 
    public MyControl() 
    { 
        InitializeComponent(); 
    } 

    public void CallView(string message) 
    { 
        MessageBox.Show(message); 
    } 
}

public class MyViewModel 
{ 
    private IMyControl myControl; 

    public IMyControl InjectedUserControl 
    { 
        set
        { 
            Debug.WriteLine(string.Format("Received Injected Control \"{0}\"", 
                value == null ? "NULL" : value.GetType().Name)); 

            this.myControl = value; 
            this.OnInjectedObjectsChanged(); 
        } 
    } 

    private void OnInjectedObjectsChanged() 
    { 
        // Directly access the view via its interface 
        if (this.myControl != null) 
            this.myControl.CallView("Hello From MyViewModel"); 
    } 
}

Чтобы загрузить демоверсию, включающую источник присоединенного свойства Injector, см. этот блог запись.Также этот предыдущий вопрос , который связан.

С уважением,

0 голосов
/ 18 января 2012

Вы захотите связать с реализацией ICommand и вызвать этот метод вашего класса.

Вот хороший блог , в котором подробно описывается использование ICommand для выполнения кода из WPF.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...