从XAML编辑器中,我可以将命名空间设置为C#项目中包含的Viewmodel
namespace ViewModelDB
{
public class DependencyViewModel : IViewModelDB
{
public string Message { get; set; }
}
}
在我的xaml
中<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ViewModelDB="clr-namespace:ViewModelDB;assembly=ViewModelDB"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
>
<UserControl.DataContext>
<ViewModelDB:DependencyViewModel/>
</UserControl.DataContext>
<Grid>
<TextBlock Text="{Binding Message}"/>
</Grid>
</UserControl>
然后识别绑定“消息”。
当我指向类似选区的F#名称空间时
namespace ModuleDBGraph
open Infrastructure
open Microsoft.Practices.Prism.Regions;
open Microsoft.Practices.Unity;
type IDependencyViewModel =
inherit IViewModel
abstract Message : string with get, set
type DependencyViewModel () =
interface IDependencyViewModel with
member val Message = "" with get, set
然后我放弃了对绑定消息的识别
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ViewModelDB="clr-namespace:ViewModelDB;assembly=ViewModelDB"
xmlns:ViewModelDBFS="clr-namespace:ModuleDBGraph;assembly=ViewModelDBGraphFS"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
>
<UserControl.DataContext>
<ViewModelDBFS:DependencyViewModel/>
</UserControl.DataContext>
<Grid>
<TextBlock Text="{Binding Message}"/>
</Grid>
</UserControl>
我做错了吗? 这是因为Message是接口IDependencyViewModel的实现和F#中接口的显式实现,这是一件好事,但是可以在这里解决这个问题吗?
答案 0 :(得分:6)
我认为没有比我们在评论中讨论过的更好的解决方案,所以我将其转化为更长的答案。
它不起作用的原因是 - 正如您已经建议的那样 - F#显式实现接口,因此当WPF是接口成员时,它不会看到Message
属性。最直接的解决方法是将其定义为显式属性(接口实现只能引用主属性):
type DependencyViewModel () =
member val Message = "" with get, set
interface IDependencyViewModel with
member x.Message with get() = x.Message and set(v) = x.Message <- v
一般来说,我认为推荐用于C#的模式在F#中并不总是很好用。例如,因为F#更简洁(使事情更容易重写)并且更不容易出错(静态捕获更多错误),我认为在这种情况下你可能根本不需要接口。
更复杂的解决方法是在运行时使用反射生成接口的隐式实现(来自显式实现),然后将其设置为DataContext
,但这对编辑器不能很好地工作,所以可能不是一个好的方向。