C#:施放到基地

时间:2016-09-12 18:35:29

标签: c# wpf mvvm

我有一个DataGrid,其中包含一个包含Link的列。单击

打开文件
<DataGridHyperlinkColumn Binding="{Binding Path=Number}" >
    <DataGridHyperlinkColumn.ElementStyle>
        <Style>
            <EventSetter Event="Hyperlink.Click" Handler="LinkClicked"/>
        </Style>
    </DataGridHyperlinkColumn.ElementStyle>
</DataGridHyperlinkColumn>

我使用这种方法

public void LinkClicked(object sender, RoutedEventArgs e) 
{
    var vm = (BasePartViewModel<Part>) DataContext;
    vm.OpenFile();
}

我想在我的Base ViewModel类中使用此代码。

但问题是此演员表不起作用

(BasePartViewModel<Part>) DataContext

因为实际上每个实现都是不同的。例如

(BasePartViewModel<Plug>) DataContext

Plug来自Part。如何在没有在每个派生的ViewModel中实现此方法的情况下使其工作?

2 个答案:

答案 0 :(得分:1)

你的问题的解决方案很简单。
很快,你已经创建了一个半MVVM实现。
当你完全使用MVVM时,不需要代码 - 并且不需要投射的事情。

MVVM对事件处理程序的回答是命令模式 (很多文章都在WWW周围)。

实现Command模式的最简单方法是滚动自己的可重用命令类。
This should get you started - 除非您已经使用某种MVVM框架。
这些通常随附他们自己的一套实施。

一旦你理解了Command模式的全部内容 -
您需要做的就是确保视图绑定到哪个ViewModel-它将预期的命令属性公开为具有公共getter的公共属性。
这使得您无需在xaml.cs文件中使用代码并且无法进行转换。

有一个示例,说明如何将命令模式应用于具有超链接here的DataGrid单元格

答案 1 :(得分:1)

您可以将OpenFile方法分解为协变接口,然后将其转换为该接口。

interface MyInterface<out T>
{
    void OpenFile();
}

class Plug : Part
{ }


class Part
{ }

class BasePartViewModel<T> : MyInterface<T>
{
    public void OpenFile()
    {
        throw new NotImplementedException();
    }
}

class Program
{
    static void Main(string[] args)
    {
        BasePartViewModel<Plug> derived = new BasePartViewModel<Plug>();
        MyInterface<Part> b = derived;
        b.OpenFile();
    }
}