我有一个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中实现此方法的情况下使其工作?
答案 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();
}
}