2013-03-18 28 views
5

veri bağlama, benXAML düzenleyicinizden bir F # ViewModel

<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> 

bağlayıcı "Message" bir C# projesi

namespace ViewModelDB 
{ 
    public class DependencyViewModel : IViewModelDB 
    { 
     public string Message { get; set; } 
    } 
} 

yılında Ve benim xaml içerdiği ViewModel ad ayarlayabilirsiniz tanıdı.

Ben o zaman bağlayıcı Mesaj tanınmasını gevşek

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 

benzer seçmen bir F # ad işaret zaman

<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> 

Yanlış mı yapıyorum? Bunun nedeni, Message IDependencyViewModel arabiriminin bir uygulaması ve F # içindeki arabirimlerin açık bir şekilde uygulanmasıdır, bu iyi bir şeydir, fakat buralarda buralarda çalışmak için var mıdır?

+0

Dediğiniz gibi - bunun nedeni muhtemelen arabirim uygulamasının açık olmasıdır. Her zamanki çözüm, yalnızca 'Message' isminin kendisine bir özellik eklemektir (ve arayüz uygulaması buna referans verebilir). –

+0

(C# yönergelerini takip etmenin F # + WPF için bu işe yaramayacağını düşünüyorum, bu yüzden kodu yazmanın daha iyi bir yolunu bulabilirsin. Örneğin, görünüm modeli arabirimine sahip olmalısın?) –

+0

Sanırım bir özellik eklemek en hafif yaklaşımdır. Ve muhtemelen bir arayüze sahip olmak çok fazla. DI için rağmen bu nokta oldukça. – nicolas

cevap

6

Yorumlarda tartıştığımızdan daha iyi bir çözüm olduğunu düşünmüyorum, bu yüzden bunu daha uzun bir cevaba çeviriyorum.

Çalışmıyor olmasının nedeni - önceden önerdiğiniz gibi - F # arabirimlerini açıkça uygular ve bu nedenle WPF, bir arabirim üyesi olduğunda Message özelliğini görmez.

Genelde
type DependencyViewModel() = 
    member val Message = "" with get, set 
    interface IDependencyViewModel with 
     member x.Message with get() = x.Message and set(v) = x.Message <- v 

, ben C# için tavsiye edilen modeller her zaman F # güzel çalışmıyor düşünüyorum: en doğrudan çözüm açık bir özellik (ve sadece ana özelliği başvurabilirsiniz arayüz uygulaması) olarak tanımlamaktır . Örneğin, F # daha kısa (yeniden yazmanın yeniden yapılması) ve daha az hataya eğilimli olduğu (daha fazla hatayı statik olarak yakaladığı) olduğundan, aslında bu durumda bir arayüze ihtiyacınız olmayabilir.

Daha karmaşık bir çözüm, çalışma zamanında yansımayı kullanarak (açık uygulamadan) arabirimin örtük bir uygulamasının oluşturulması ve daha sonra DataContext olarak ayarlanmasıdır, ancak editörlerle güzel şekilde çalışmayacaktır, bu yüzden iyi bir yön olmayabilir .

+0

haklısınız. her yerde çıldırmamalı ve bağımlılık enjeksiyonu yapmamalıyız. DI yararlıdır, ama en önemlisi en fazla değişime sahip olduğumuz yerde. Bu, bir uygulamanın işlevsel bileşeninde, farklı algoritma, arka uç depolama alanı vb. Sadece bazı arayüzler koyabildiğimiz için (ve çok sık seve seve yaparsak) onları her yere koymamız gerektiği anlamına gelmez. – nicolas