c#:转换为基

本文关键字:转换 | 更新日期: 2023-09-27 18:06:38

我有一个包含链接的列的DataGrid。点击

打开文件
<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?

c#:转换为基

您可以将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();
    }
}

解决你的问题很简单。简单地说,您已经创建了一个半MVVM实现。
当你使用完整的MVVM时,不需要后面的代码,也不需要强制类型转换。

MVVM对事件处理程序的回答是Command模式。
(WWW上有很多文章)。

实现Command模式的最简单方法是滚动您自己的可重用命令类。
这应该让你开始-除非你已经在使用某种MVVM框架。
它们通常有自己的一组实现。

一旦你理解了Command模式是关于什么的-
你所需要做的就是确保无论视图绑定到哪个ViewModel——
,它都有预期的命令属性,作为带有公共getter的公共属性公开。
这使您不必在xaml.cs文件中编写代码,也不必进行强制转换。

这里有一个如何将命令模式应用于带有超链接的DataGrid单元格的示例