Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ViewModel是否应直接引用视图对象?_C#_Mvvm_Xamarin.forms - Fatal编程技术网

C# ViewModel是否应直接引用视图对象?

C# ViewModel是否应直接引用视图对象?,c#,mvvm,xamarin.forms,C#,Mvvm,Xamarin.forms,“我的视图”中有一个控件,它能够生成保存在我可以指定的路径(以及其他一些数据)上的图像。我不拥有此控件,无法更改生成图像的界面。我不太确定如何用MVVM处理这个问题 对于我的视图来说,快速而肮脏的方法是定义一个采用所需路径的方法,并让viewmodel调用该方法 View: public void GenerateImage(string path) { _control.SaveImage(path); } ViewModel: (actually this is the body

“我的视图”中有一个控件,它能够生成保存在我可以指定的路径(以及其他一些数据)上的图像。我不拥有此控件,无法更改生成图像的界面。我不太确定如何用MVVM处理这个问题

对于我的视图来说,快速而肮脏的方法是定义一个采用所需路径的方法,并让viewmodel调用该方法

View:
public void GenerateImage(string path) {
    _control.SaveImage(path);
}

ViewModel:
(actually this is the body of a Command) {
    var path = GeneratePath();
    _view.GenerateImage(path);
    ...
}
我不喜欢这样,因为我觉得viewmodels并不是直接引用视图,而是表示视图的状态,并通过属性绑定进行通信。它是有效的,我在等待答案的时候就这么做了。我想找个办法绕过它

我可以让视图通过Execute()参数将对控件的引用传递给命令(我使用的是Xamarin表单),然后让命令强制转换并进行调用。这看起来像猪上的口红,因为它使VIEW模型仍然能感知到视图中的特定类。但在写这一段时,我想我想出了一个我喜欢的解决办法

我/可以/创造:

interface IGenerateImage {
    void GenerateImage(string path);
}
显而易见的实现是将调用委托给封装的控件。我觉得如果视图传递了一个
IGenerateImage
,那么我就不会创建viewmodel来查看我试图避免的依赖关系,我可以测试逻辑,而无需实例化昂贵的UI类


我喜欢这个答案,但我很确定我错过了一个显而易见的解决方案。是否有其他有用的模式来处理它?或者,如果视图模型引用视图,这不是什么大问题吗?

您永远不希望视图模型知道有关视图的任何信息

在你的帖子中,什么是可以更改的,什么是不能更改的,这有点不清楚,所以我假设你可以更改V/VM,但不能更改控制

最简单的方法是在视图模型中创建一个视图可以订阅的事件

大概是这样的:

视图:

视图模型:

public event EventHandler<ImageGeneratedEventArgs> ImageGeneratedEvent;

// Command body
{
    var path = GeneratePath();

    // Send event to the View
    this.NotifyImageGeneratedEvent(path)
}

private void NotifyImageGeneratedEvent(string path)
{
    ImageGeneratedEventArgs args = new ImageGeneratedEventArgs(path);

    if (this.ImageGeneratedEvent!= null)
    {
        this.ImageGeneratedEvent(this, args);
    }
}

您永远不希望视图模型了解有关视图的任何信息

在你的帖子中,什么是可以更改的,什么是不能更改的,这有点不清楚,所以我假设你可以更改V/VM,但不能更改控制

最简单的方法是在视图模型中创建一个视图可以订阅的事件

大概是这样的:

视图:

视图模型:

public event EventHandler<ImageGeneratedEventArgs> ImageGeneratedEvent;

// Command body
{
    var path = GeneratePath();

    // Send event to the View
    this.NotifyImageGeneratedEvent(path)
}

private void NotifyImageGeneratedEvent(string path)
{
    ImageGeneratedEventArgs args = new ImageGeneratedEventArgs(path);

    if (this.ImageGeneratedEvent!= null)
    {
        this.ImageGeneratedEvent(this, args);
    }
}

您永远不希望视图模型了解有关视图的任何信息

在你的帖子中,什么是可以更改的,什么是不能更改的,这有点不清楚,所以我假设你可以更改V/VM,但不能更改控制

最简单的方法是在视图模型中创建一个视图可以订阅的事件

大概是这样的:

视图:

视图模型:

public event EventHandler<ImageGeneratedEventArgs> ImageGeneratedEvent;

// Command body
{
    var path = GeneratePath();

    // Send event to the View
    this.NotifyImageGeneratedEvent(path)
}

private void NotifyImageGeneratedEvent(string path)
{
    ImageGeneratedEventArgs args = new ImageGeneratedEventArgs(path);

    if (this.ImageGeneratedEvent!= null)
    {
        this.ImageGeneratedEvent(this, args);
    }
}

您永远不希望视图模型了解有关视图的任何信息

在你的帖子中,什么是可以更改的,什么是不能更改的,这有点不清楚,所以我假设你可以更改V/VM,但不能更改控制

最简单的方法是在视图模型中创建一个视图可以订阅的事件

大概是这样的:

视图:

视图模型:

public event EventHandler<ImageGeneratedEventArgs> ImageGeneratedEvent;

// Command body
{
    var path = GeneratePath();

    // Send event to the View
    this.NotifyImageGeneratedEvent(path)
}

private void NotifyImageGeneratedEvent(string path)
{
    ImageGeneratedEventArgs args = new ImageGeneratedEventArgs(path);

    if (this.ImageGeneratedEvent!= null)
    {
        this.ImageGeneratedEvent(this, args);
    }
}

显然,视图必须以某种方式引用ViewModel才能显示它。如果你有一个来自ViewModel的视图引用,你就会有一个循环依赖关系——你应该永远不想在任何设计中这样做。是的,这让我觉得VM->view引用不是一个好主意。视图->虚拟机引用是必需的,因为您必须设置DataContext。通常,您会在ViewModel中创建一些内容,该更改会在视图中引起通知,然后该通知将读取(并可能处理)数据。我觉得GenerateImage方法应该在viewmodel(或模型)中。显然,视图必须以某种方式引用viewmodel才能显示它。如果你有一个来自ViewModel的视图引用,你就会有一个循环依赖关系——你应该永远不想在任何设计中这样做。是的,这让我觉得VM->view引用不是一个好主意。视图->虚拟机引用是必需的,因为您必须设置DataContext。通常,您会在ViewModel中创建一些内容,该更改会在视图中引起通知,然后该通知将读取(并可能处理)数据。我觉得GenerateImage方法应该在viewmodel(或模型)中。显然,视图必须以某种方式引用viewmodel才能显示它。如果你有一个来自ViewModel的视图引用,你就会有一个循环依赖关系——你应该永远不想在任何设计中这样做。是的,这让我觉得VM->view引用不是一个好主意。视图->虚拟机引用是必需的,因为您必须设置DataContext。通常,您会在ViewModel中创建一些内容,该更改会在视图中引起通知,然后该通知将读取(并可能处理)数据。我觉得GenerateImage方法应该在viewmodel(或模型)中。显然,视图必须以某种方式引用viewmodel才能显示它。如果你有一个来自ViewModel的视图引用,你就会有一个循环依赖关系——你应该永远不想在任何设计中这样做。是的,这让我觉得VM->view引用不是一个好主意。视图->虚拟机引用是必需的,因为您必须设置DataContext。通常,您会在ViewModel中创建一些内容,该更改会在视图中引起通知,然后该通知将读取(并可能处理)数据。我觉得GenerateImage方法应该在viewmodel(或模型)中。