MVVM中运行时的Onload绑定错误

时间:2016-02-19 10:27:58

标签: c# wpf mvvm data-binding

我试图将MVVM Light框架用于" OnLoad"查看函数,以便在加载表单时执行ViewModel中的函数。

我已经按照几个链接的例子实现了这个目标:

https://stackoverflow.com/a/3409801/2794484 http://aslamhadi.com/add-onload-event-in-wpf-mvvm/ https://social.msdn.microsoft.com/Forums/vstudio/en-US/b4d2afe6-4c28-44e5-98a5-b7ba30fec220/how-to-capture-window-loaded-event-in-view-model-when-using-mvvm?forum=wpf

我的观点有:

<i:Interaction.Triggers>
    <i:EventTrigger EventName="Loaded">
        <GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding LoadWindowCommand, Mode=OneWay}" />
    </i:EventTrigger>
</i:Interaction.Triggers>

我的ViewModel:

    public TestViewModel()
    {
        LoadWindowCommand = new RelayCommand(OnLoadWindowCommand);
    }

    public RelayCommand LoadWindowCommand { get; private set; }
    private void OnLoadWindowCommand()
    {
        //put your code here
    }

它可以工作,但使用任何链接的方法,在运行时引发了一个绑定错误:

System.Windows.Data信息:10:无法使用绑定检索值,并且不存在有效的回退值;使用默认值。 BindingExpression:路径= LoadWindowCommand;的DataItem = NULL;目标元素是&#39; EventToCommand&#39; (的HashCode = 4875788);目标财产是&#39; Command&#39; (键入&#39; ICommand&#39;)

如何避免此错误?

更新,我已将所有代码更新为您的建议。

的MainView:

<Window x:Class="MvvmLight1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:GalaSoft_MvvmLight_Command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4"
       xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
        xmlns:ignore="http://www.ignore.com"
        xmlns:local="clr-namespace:MvvmLight1.ViewModel"
        mc:Ignorable="d ignore"
        Title="MVVM Light Application" Height="300" Width="300">
    <Window.Resources>
        <local:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
    </Window.Resources>
    <Window.DataContext>
        <!--Move DataContext binding there-->
        <Binding Path="Main" Source="{StaticResource Locator}"/>
    </Window.DataContext>
    <Grid>
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Loaded">
                <GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding LoadWindowCommand, Mode=OneWay}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </Grid>
</Window>

视图模型:

class MainWindowViewModel : ViewModelBase
{
    public MainWindowViewModel()
    {
        LoadWindowCommand = new RelayCommand(OnLoadWindowCommand);
    }

    public RelayCommand LoadWindowCommand { get; private set; }
    private void OnLoadWindowCommand()
    {
        Debug.WriteLine("Loaded!");
    }
}

ViewModelLocator

class ViewModelLocator
{
    public ViewModelLocator()
    {
        Main = new MainWindowViewModel();
    }

    public MainWindowViewModel Main { get; private set; }
}

我在App.xaml中评论了以下几行:

<!--<Application.Resources>
    <vm:ViewModelLocator x:Key="Locator"
                         d:IsDataSource="True" />
</Application.Resources>-->    

但在我的&#34;输出&#34; Windows我继续看到:

....
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=LoadWindowCommand; DataItem=null; target element is 'EventToCommand' (HashCode=44967810); target property is 'Command' (type 'ICommand')
'MvvmLight1.vshost.exe' (Administrado (v4.0.30319)): se cargó 'C:\windows\Microsoft.Net\assembly\GAC_MSIL\PresentationFramework.Aero\v4.0_4.0.0.0__31bf3856ad364e35\PresentationFramework.Aero.dll', se omitió la carga de símbolos. Se optimizó el módulo y se habilitó la opción 'Solo mi código'.
'MvvmLight1.vshost.exe' (Administrado (v4.0.30319)): se cargó 'C:\windows\Microsoft.Net\assembly\GAC_MSIL\UIAutomationProvider\v4.0_4.0.0.0__31bf3856ad364e35\UIAutomationProvider.dll', se omitió la carga de símbolos. Se optimizó el módulo y se habilitó la opción 'Solo mi código'.
'MvvmLight1.vshost.exe' (Administrado (v4.0.30319)): se cargó 'C:\windows\Microsoft.Net\assembly\GAC_MSIL\UIAutomationTypes\v4.0_4.0.0.0__31bf3856ad364e35\UIAutomationTypes.dll', se omitió la carga de símbolos. Se optimizó el módulo y se habilitó la opción 'Solo mi código'.
Loaded!

我可以在代码中看到的唯一区别是MainWindow的名称空间参考:

xmlns:mvvm_light_cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Platform"

我的:

xmlns:GalaSoft_MvvmLight_Command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4"

如果我添加你的命名空间,它会返回并错误地尝试解析&#34; GalaSoft.MvvmLight.Platform&#34;

有什么建议吗?

1 个答案:

答案 0 :(得分:2)

好的,我已经知道了。问题是您在初始化之前尝试获取Locator资源。只需将资源部分放在DataContext绑定之后。这是代码:

<强> MainWindow.xaml

<Window x:Class="MvvmLight1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:GalaSoft_MvvmLight_Command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras"
       xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
        xmlns:ignore="http://www.ignore.com"
        xmlns:local="clr-namespace:MvvmLight1.ViewModel"
        mc:Ignorable="d ignore"
        Title="MVVM Light Application" Height="300" Width="300">
    <Window.Resources>
        <local:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
    </Window.Resources>
    <Window.DataContext>
        <!--Move DataContext binding there-->
        <Binding Path="Main" Source="{StaticResource Locator}"/>
    </Window.DataContext>
    <Grid>
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Loaded">
                <GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding LoadWindowCommand, Mode=OneWay}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </Grid>
</Window>

<强> MainViewModel.cs

namespace MvvmLight1.ViewModel
{
    public class MainViewModel : ViewModelBase
    {
        public MainViewModel()
        {
            LoadWindowCommand = new RelayCommand(OnLoadWindowCommand);
        }

        public RelayCommand LoadWindowCommand { get; private set; }
        private void OnLoadWindowCommand()
        {
            Debug.WriteLine("Loaded!");
        }
    }
}

<强> ViewModelLocator.cs

namespace MvvmLight1.ViewModel
{
    public class ViewModelLocator
    {

        public ViewModelLocator()
        {
            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
            SimpleIoc.Default.Register<MainViewModel>();
        }

        public MainViewModel Main
        {
            get
            {
                return ServiceLocator.Current.GetInstance<MainViewModel>();
            }
        }
    }
}