简体   繁体   English

在WPF应用程序中实现服务层

[英]Implement Service Layer in WPF application

I am working on WPF application and new to it so this might be a dumb question, 我正在研究WPF应用程序及其新功能,所以这可能是一个愚蠢的问题,

What I would like to do is trigger binding from my service layer. 我想做的是从服务层触发绑定。 To explain better I have created an example. 为了更好地解释,我创建了一个示例。 In this example, I would like to bind grid with logged messags(from service method) on my WPF screen. 在此示例中,我想将WPF屏幕上的已记录消息(来自service方法)绑定到网格。

See my comment in ServiceMethod in Service class. 请参阅Service类中ServiceMethod中的我的评论。 This is the place I would like to trigger binding. 这是我想触发绑定的地方。

I tried to explain with best possible way but do not hesitate if you need further clarification on this. 我试图以最好的方式进行解释,但是如果您需要进一步的说明,请不要犹豫。

XAML XAML

<Window x:Class="WpfApp1.ServiceExample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="ServiceExample" Height="300" Width="300">
    <Window.Resources>
        <local:ServiceExampleViewModel x:Key="serviceExampleViewModel"></local:ServiceExampleViewModel>
    </Window.Resources>
    <Grid>
        <StackPanel Orientation="Vertical">
            <DataGrid ItemsSource="{Binding MessageLog,
                    Source={StaticResource serviceExampleViewModel},
                    Mode=TwoWay,
                    UpdateSourceTrigger=PropertyChanged}">
            </DataGrid>
            <Button Content="Call Service" Command="{Binding CallService,
                Mode=TwoWay, Source={StaticResource serviceExampleViewModel}}"></Button>
            <Label Content="{Binding ServiceResult, 
                    Source={StaticResource serviceExampleViewModel},
                    Mode=TwoWay,
                    UpdateSourceTrigger=PropertyChanged}"></Label>
        </StackPanel>

    </Grid>
</Window>

ServiceExample 服务实例

public partial class ServiceExample : Window
{
    public ServiceExample()
    {
        InitializeComponent();
    }
}

btnClick btnClick

public class btnClick : System.Windows.Input.ICommand
{
    private Action WhatToExecute;
    private Func<bool> WhenToExecute;
    public btnClick(Action what, Func<bool> when)
    {
        WhatToExecute = what;
        WhenToExecute = when;
    }
    public void Refresh()
    {
        if (this.CanExecuteChanged != null)
        {
            CanExecuteChanged(this, EventArgs.Empty);
        }
    }
    public event EventHandler CanExecuteChanged;
    public bool CanExecute(object parameter)
    {
        return WhenToExecute();
    }
    public void Execute(object parameter)
    {
        WhatToExecute();
    }
}

ServiceExampleViewModel ServiceExampleViewModel

class ServiceExampleViewModel : System.ComponentModel.INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private int serviceResult;
    public int ServiceResult
    {
        get { return serviceResult; }
        set
        {
            serviceResult = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("ServiceResult"));
        }
    }
    public btnClick CallService { get; set; }
    public Service ServiceObj { get; set; }
    public ServiceExampleViewModel()
    {
        ServiceObj = new Service();
        this.CallService = new btnClick(CallServiceMethod, () => { return true; });
    }

    private void CallServiceMethod()
    {
        this.ServiceResult = this.ServiceObj.ServiceMethod();
    }
}

Message 信息

class Message
{
    public string Text { get; set; }
}

Service 服务

class Service
{
    public List<Message> MessageLog;

    public Service()
    {
        this.MessageLog = new List<Message>();
    }

    public int ServiceMethod()
    {
        int result = 0;
        for (int counter = 0; counter < 10; ++counter)
        {
            //This is where binding should trigger
            this.MessageLog.Add(new Message() { Text = string.Format("{0}:{1}", DateTime.Now.Ticks, counter) });

            result += counter;
        }
        return result;
    }
}

In MVVM you don't have bindings from a service, not ever. 在MVVM中,您永远不会有来自服务的绑定。 The purpose of a service is to be a conduit of data, maybe with some limited business logic in it. 服务的目的是成为数据的管道,其中可能包含一些有限的业务逻辑。 Services can have a very short lifetime and they typically don't maintain any state. 服务的寿命可能很短,并且通常不维护任何状态。

Your bindings should be between your view and your viewmodel, to bind any other way is violating the pattern. 您的绑定应该在视图和视图模型之间,以任何其他方式绑定都违反了模式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM