tôi cần một ví dụ của việc này vì vậy tôi đã viết một cách sử dụng các kỹ thuật khác nhau.
tôi đã có một vài mục tiêu thiết kế trong tâm trí
1 - giữ nó đơn giản
2 - hoàn toàn không có code-behind trong giao diện (class Window)
3 - chứng minh một sự phụ thuộc của chỉ Tham chiếu hệ thống trong thư viện lớp ViewModel.
4 - giữ logic nghiệp vụ trong ViewModel và định tuyến trực tiếp đến các phương thức thích hợp mà không cần viết một loạt các phương thức "sơ khai".
Dưới đây là các mã ...
App.xaml (không StartupUri là điều duy nhất đáng chú ý)
<Application
x:Class="WpfApplicationCleanSeparation.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
</Application>
App.xaml.cs (tải lên giao diện chính)
using System.Windows;
using WpfApplicationCleanSeparation.ViewModels;
namespace WpfApplicationCleanSeparation
{
public partial class App
{
protected override void OnStartup(StartupEventArgs e)
{
var view = new MainView();
var viewModel = new MainViewModel();
view.InitializeComponent();
view.DataContext = viewModel;
CommandRouter.WireMainView(view, viewModel);
view.Show();
}
}
}
CommandRouter.cs (ma thuật)
using System.Windows.Input;
using WpfApplicationCleanSeparation.ViewModels;
namespace WpfApplicationCleanSeparation
{
public static class CommandRouter
{
static CommandRouter()
{
IncrementCounter = new RoutedCommand();
DecrementCounter = new RoutedCommand();
}
public static RoutedCommand IncrementCounter { get; private set; }
public static RoutedCommand DecrementCounter { get; private set; }
public static void WireMainView(MainView view, MainViewModel viewModel)
{
if (view == null || viewModel == null) return;
view.CommandBindings.Add(
new CommandBinding(
IncrementCounter,
(λ1, λ2) => viewModel.IncrementCounter(),
(λ1, λ2) =>
{
λ2.CanExecute = true;
λ2.Handled = true;
}));
view.CommandBindings.Add(
new CommandBinding(
DecrementCounter,
(λ1, λ2) => viewModel.DecrementCounter(),
(λ1, λ2) =>
{
λ2.CanExecute = true;
λ2.Handled = true;
}));
}
}
}
MainView.xaml (không có mã-đằng sau, nghĩa là xóa!)
<Window
x:Class="WpfApplicationCleanSeparation.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:WpfApplicationCleanSeparation="clr-namespace:WpfApplicationCleanSeparation"
Title="MainWindow"
Height="100"
Width="100">
<StackPanel>
<TextBlock Text="{Binding Counter}"></TextBlock>
<Button Content="Decrement" Command="WpfApplicationCleanSeparation:CommandRouter.DecrementCounter"></Button>
<Button Content="Increment" Command="WpfApplicationCleanSeparation:CommandRouter.IncrementCounter"></Button>
</StackPanel>
</Window>
MainViewModel.cs (bao gồm mô hình thực tế cũng từ ví dụ này là rất đơn giản, xin vui lòng tha các derailing của mô hình MVVM.
using System.ComponentModel;
namespace WpfApplicationCleanSeparation.ViewModels
{
public class CounterModel
{
public int Data { get; private set; }
public void IncrementCounter()
{
Data++;
}
public void DecrementCounter()
{
Data--;
}
}
public class MainViewModel : INotifyPropertyChanged
{
private CounterModel Model { get; set; }
public event PropertyChangedEventHandler PropertyChanged = delegate { };
public MainViewModel()
{
Model = new CounterModel();
}
public int Counter
{
get { return Model.Data; }
}
public void IncrementCounter()
{
Model.IncrementCounter();
PropertyChanged(this, new PropertyChangedEventArgs("Counter"));
}
public void DecrementCounter()
{
Model.DecrementCounter();
PropertyChanged(this, new PropertyChangedEventArgs("Counter"));
}
}
}
Chỉ cần một cách nhanh chóng và dơ bẩn và tôi hy vọng nó hữu ích cho một ai đó. Tôi thấy một vài cách tiếp cận khác nhau thông qua Google khác nhau nhưng không có gì đơn giản và dễ thực hiện với số lượng mã ít nhất có thể mà tôi muốn. Nếu có một cách để đơn giản hóa hơn nữa xin vui lòng cho tôi biết, cảm ơn.
Chúc mừng Mã hóa :)
EDIT: Để đơn giản hóa mã của riêng tôi, bạn có thể tìm thấy điều này hữu ích cho việc các Thêm vào một lớp lót.
private static void Wire(this UIElement element, RoutedCommand command, Action action)
{
element.CommandBindings.Add(new CommandBinding(command, (sender, e) => action(), (sender, e) => { e.CanExecute = true; }));
}
@aoven: tôi nơi bạn đã khi bạn hỏi này 8 tháng trước, và tự hỏi những gì bạn vết thương lên và làm thế nào nó lo lắng d nó ra cho bạn. Chúc mừng – Berryl