Обратите внимание, что это на самом деле не отвечает на вопросы (я должен был прочитать лучше).Если вы заинтересованы в использовании элемента управления WPF в приложении WinForms, вот подход.Мой сценарий: 1) У меня есть элемент управления WinForms, который используется во многих местах моего приложения.2) Хотите разработать реализацию WPF, которая будет использовать шаблон MVVM.3) Хотите написать элемент управления как надлежащий WPF-элемент управления со свойствами зависимостей, чтобы его можно было правильно использовать, когда мое приложение в конечном итоге будет полностью WPF.4) Хотите сохранить тот же элемент управления WinForms и API, чтобы не нарушать существующий клиентский код в моем приложении.
Большинство всего было простым, за исключением того, что мой элемент управления WinForms вызывал события, когда изменялись свойства моего элемента управления WPF.Я хотел использовать привязку, но поскольку источником привязки должен быть DependencyObject, а System.Windows.Forms.UserControl - нет, мне пришлось создать простой вложенный класс.Я написал свой элемент управления WPF точно так же, как если бы я интегрировал его в приложение WPF, и просто сделал несколько дополнительных шагов, чтобы заставить работать мою оболочку WinForms.
Вот код для моего элемента управления WPF:
public partial class MonkeySelector : UserControl
{
public static readonly DependencyProperty SelectedMonkeyProperty =
DependencyProperty.Register(
"SelectedMonkey", typeof(IMonkey),
typeof(MonkeySelector));
public MonkeySelector()
{
InitializeComponent();
}
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
// Note: No code is shown for binding the SelectedMonkey dependency property
// with the ViewModel's SelectedMonkey property. This is done by creating
// a Binding object with a source of ViewModel (Path = SelectedMonkey) and
// target of the SelectedMonkey dependency property. In my case, my
// ViewModel was a resource declared in XAML and accessed using the
// FindResource method.
}
public IMonkey SelectedMonkey
{
get { return (IMonkey)GetValue(SelectedMonkeyProperty); }
set { SetValue(SelectedMonkeyProperty, value); }
}
}
Вот код для моего элемента управления WinForms:
public partial class WinFormsMonkeySelector : UserControl
{
public event EventHandler SelectedMonkeyChanged;
private MonkeySelector _monkeySelector;
private WpfThunker _thunker;
public WinFormsMonkeySelector()
{
InitializeComponent();
_monkeySelector = new MonkeySelector();
_elementHost.Child = _monkeySelector;
System.Windows.Data.Binding binding = new System.Windows.Data.Binding("SelectedMonkey");
binding.Source = _monkeySelector;
binding.Mode = System.Windows.Data.BindingMode.OneWay;
_thunker = new WpfThunker(this);
// Note: The second parameter here is arbitray since we do not actually
// use it in the thunker. It cannot be null though. We could declare
// a DP in the thunker and bind to that, but that isn't buying us anything.
System.Windows.Data.BindingOperations.SetBinding(
_thunker,
MonkeySelector.SelectedMonkeyProperty,
binding);
}
protected virtual void OnSelectedMonkeyChanged()
{
if (SelectedMonkeyChanged != null)
SelectedMonkeyChanged(this, EventArgs.Empty);
}
public IMonkey SelectedMonkey
{
get { return _monkeySelector.SelectedMonkey; }
set { _monkeySelector.SelectedMonkey = value; }
}
private class WpfThunker : System.Windows.DependencyObject
{
private WinFormsMonkeySelector _parent;
public WpfThunker(WinFormsMonkeySelector parent)
{
_parent = parent;
}
protected override void OnPropertyChanged(System.Windows.DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
// Only need to check the property here if we are binding to multiple
// properties.
if (e.Property == MonkeySelector.SelectedMonkeyProperty)
_parent.OnSelectedMonkeyChanged();
}
}
}