0

私が取り組んでいるWindows 7電話アプリケーションがあります。インターフェイスを使用していくつかのサービス クラスを作成しましたが、これらのビューをナビゲートしようとするたびにクラッシュします。

エミュレーターが (WMAppManifest.xml を介して) 読み込まれるとすぐに、これらのビューのいずれかを読み込むようにプロジェクトをセットアップします。

私はこのようなものを持っています

 public interface IGpsService
    {
        void StartGps();
        GeoPosition<GeoCoordinate> CurrentPostion();
    }


public class GpsService : IGpsService
{
    private GeoCoordinateWatcher gpsWatcher;

    public GpsService()
    {
        gpsWatcher = new GeoCoordinateWatcher(GeoPositionAccuracy.Default)
        {
            MovementThreshold = 20,
        };

    }

    public void StartGps()
    {
        gpsWatcher.Start();
    }

    public GeoPosition<GeoCoordinate> CurrentPostion()
    {
        return gpsWatcher.Position;
    }

}

私のビュー モデル ロケータ

   static ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

        if (ViewModelBase.IsInDesignModeStatic)
        {
            SimpleIoc.Default.Register<IGpsService, Design.GpsDataService>();
        }
        else
        {
            SimpleIoc.Default.Register<IGpsService, GpsService>();
        }
        SimpleIoc.Default.Register<AddProductPriceVm>();
    }

// AddProductPrice.xaml.cs

 public AddProductPrice(IGpsService gpsService)
    {
        InitializeComponent();
    }

Ioc はビュー モデルなどにのみバインドしますか? コードビハインドにあるので、それが機能しないのはなぜですか?

私はコードビハインドと MVVM を組み合わせて使用​​しています。コードビハインドの方がはるかに簡単です。

エラーメッセージ

MissingMethodException
   at System.Activator.InternalCreateInstance(Type type, Boolean nonPublic, StackCrawlMark& stackMark)
   at System.Activator.CreateInstance(Type type)
   at System.Windows.Navigation.PageResourceContentLoader.BeginLoad_OnUIThread(AsyncCallback userCallback, PageResourceContentLoaderAsyncResult result)
   at System.Windows.Navigation.PageResourceContentLoader.<>c__DisplayClass4.<BeginLoad>b__0(Object args)
   at System.Reflection.RuntimeMethodInfo.InternalInvoke(RuntimeMethodInfo rtmi, Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
   at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at System.Delegate.DynamicInvokeOne(Object[] args)
   at System.MulticastDelegate.DynamicInvokeImpl(Object[] args)
   at System.Delegate.DynamicInvoke(Object[] args)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.Dispatch(DispatcherPriority priority)
   at System.Windows.Threading.Dispatcher.OnInvoke(Object context)
   at System.Windows.Hosting.CallbackCookie.Invoke(Object[] args)
   at System.Windows.Hosting.DelegateWrapper.InternalInvoke(Object[] args)
   at System.Windows.RuntimeHost.ManagedHost.InvokeDelegate(IntPtr pHandle, Int32 nParamCount, ScriptParam[] pParams, ScriptParam& pResult)

ナビゲーション失敗のダイ

   // Code to execute if a navigation fails
    private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
    {
        if (System.Diagnostics.Debugger.IsAttached)
        {
            // A navigation has failed; break into the debugger
            System.Diagnostics.Debugger.Break();
        }
    }
4

1 に答える 1

0

ビューモデルではなく、ビューに直接サービスを注入しています。ビューは SimpleIoc を使用して作成されていないため、コンストラクターで IGpsService 参照を解決する場所がわかりません。

これを行う場合の最善の策は、IGpsService をビューモデルに挿入し、それをプロパティとして公開することです。ビューに DataContextChanged イベントを追加し、それが発生したら、viewmodel から IGpsService を取得します。

編集:

//AddProductPrice ビュー

<UserControl
DataContext="{StaticResource  Locator.AddProductPriceVm}">

/ AddProductPrice.xaml.cs

public AddProductPrice()
    {
        InitializeComponent();
        DataContextChanged+=DataContextChanged
    }
        void DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            var context=sender as AddProductPriceVm;
            if(context!=null)
                _myGpsService=context.GpsService;
        }

//AddProductPriceVm

public class AddProductPriceVm
{
public AddProductPriceVm(IGpsService gpsService)
{
   GpsService=gpsService;
}
public IGpsService GpsService{get;set;}
}

この問題は実際には DI の問題ではなく、MVVM Light がどのように機能するかだけです。依存性注入を実行する前に、ビューがそこにあることを期待しています。ビューに何かを直接注入したい場合は、Prism を使用することを検討できます (ただし、より多くの足場を使用すると、はるかに重くなります)。

于 2013-07-23T08:34:22.740 に答える