5

在 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# 中接口的显式实现,这是一件好事,但是这里有办法解决这个问题吗?

4

1 回答 1

6

我认为没有比我们在评论中讨论的解决方案更好的解决方案,因此我将其转换为更长的答案。

它不起作用的原因是 - 正如您已经建议的那样 - F# 显式实现接口,因此 WPFMessage在它是接口成员时看不到该属性。最直接的解决方法是将其定义为显式属性(接口实现可以只引用主属性):

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但这不能很好地与编辑器一起工作,所以这可能不是一个好的方向。

于 2013-03-18T17:23:47.430 回答