【问题标题】:Binding to another viewmodel绑定到另一个视图模型
【发布时间】:2023-03-07 19:54:01
【问题描述】:

我正在尝试将可见性属性绑定到我在视图模型 (MainViewModel) 中创建的函数,但出现此错误:

“System.IO.FileNotFoundException”类型的第一次机会异常发生在 mscorlib.dll 中 System.Windows.Data 错误:BindingExpression 路径错误:在“Locator”“System.String”上找不到“Main”属性(HashCode=-191326816)。 BindingExpression: Path='Main.TilesHomeViewVisible' DataItem='Locator' (HashCode=-191326816);目标元素是'myApp.Views.TilesHomeView'(名称='myTilesHomeView');目标属性是“可见性”(类型“System.Windows.Visibility”)..

根据我对错误的理解,它正在寻找TilesHomeViewModel 中的TilesHomeViewVisible 函数,而它实际上在MainViewModel 中。在绑定表达式中,那我该如何定位MainViewModel呢?

编辑:我集成了一个“ViewModelLocator”。

这是我的 ViewModelLocator:

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

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

    public TilesHomeViewModel TilesVM
    {
        get
        {
            return ServiceLocator.Current.GetInstance<TilesHomeViewModel>();
        }
    }
...

我的 App.xaml:

<?xml version="1.0" encoding="utf-8"?>
<Application x:Class="myApp.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:app="clr-namespace:myApp" mc:Ignorable="d"
             xmlns:views="clr-namespace:myApp.Views"
             xmlns:vm="clr-namespace:myApp.ViewModels">

    <!--Application Resources-->
    <Application.Resources>
    <ResourceDictionary>
        <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary>
                    <app:ColorWrapper x:Key="ColorWrapper" />
                </ResourceDictionary>
                <ResourceDictionary x:Name="ResourceDictionary1" Source="ResourceDictionary1.xaml"/>
            </ResourceDictionary.MergedDictionaries>

    </ResourceDictionary>

    </Application.Resources>

    <Application.ApplicationLifetimeObjects>
        <!--Required object that handles lifetime events for the application-->
        <shell:PhoneApplicationService Launching="Application_Launching" Closing="Application_Closing" Activated="Application_Activated" Deactivated="Application_Deactivated" />
    </Application.ApplicationLifetimeObjects>

</Application>

在我的 MainPage.xaml 和定位器的链接中,我有:

<phone:PhoneApplicationPage
    ...
    d:DataContext="{d:DesignData SampleData/MainViewModelSampleData.xaml}"
    ...
>
    <phone:PhoneApplicationPage.DataContext>
        <Binding Path="Main" Source="{StaticResource Locator}"/>
    </phone:PhoneApplicationPage.DataContext>
    ...
    <Grid x:Name="LayoutRoot">
        ...
        <local:TilesHomeView x:Name="myTilesHomeView" Visibility="{Binding Main.TilesHomeViewVisible,Source=Locator}" />
    </Grid>
</phone:PhoneApplicationPage>      

MainViewModel.cs

public class MainViewModel : ViewModelBase
    {
    public MainViewModel()
    {
        this.Items = new ObservableCollection<ItemViewModel>(); 
    }
    Visibility _tilesHomeViewVisible = System.Windows.Visibility.Collapsed;

    public Visibility TilesHomeViewVisible
    {
        get { return System.Windows.Visibility.Collapsed; }
        set { _tilesHomeViewVisible = value; RaisePropertyChanged("TilesHomeViewVisible"); }
    }

    public void TilesHomeViewClose()
    {
        TilesHomeViewVisible = System.Windows.Visibility.Collapsed;
    }
    public bool IsDataLoaded
    {
        get;
        private set;
    }
    /// <summary>
    /// Creates and adds a few ItemViewModel objects into the Items collection.
    /// </summary>
    public void LoadData()
    {...}
}

TilesHomeView.xaml 的数据上下文定义如下:

<UserControl x:Class="myApp.Views.TilesHomeView"
....
DataContext="{Binding TilesVM, Source={StaticResource Locator}}"
>

    <Grid x:Name="HomeGrid">
    </Grid>
</UserControl>

HomeViewModel.cs 没有任何功能,就这样呈现

namespace myApp
{
    public class TilesHomeViewModel : ViewModelBase
    {
        public TilesHomeViewModel()
        {
        }
    }
}

我希望这尽可能详细。我真的希望找到解决此错误的方法,这已经困扰了我好几天了。

谢谢

【问题讨论】:

  • 发布页面的.xaml,需要的是绑定的上下文,而不是绑定的定义。
  • 请把代码贴在后面
  • 我已经用更多代码更新了我的帖子以详细说明情况。请看一看。谢谢

标签: c# windows-phone-7 silverlight-4.0 mvvm-light


【解决方案1】:

问题是您可能正在将 TilesHomeViewModel 设置为 TilesHomeView 用户控件根上的 DataContext(这意味着 TilesHomeView 元素的 DataContext 也是 TilesHomeView )。
这里有两种可能的解决方案:

在设置可见性时明确设置来源:

<local:TilesHomeView x:Name="myTilesHomeView" Visibility="{Binding Main.TilesHomeViewVisible,Source={StaticResource Locator} }" />

(使用定位器上的适当值更新)

-第二个解决方案是移动在 UserControl 中将 DataContext 设置为 TilesHomeViewModel 的位置:将 DataContext 设置为用户控件的 LayoutRoot 网格而不是根。

【讨论】:

  • 您好,我使用了您提供的代码,但仍然找不到该功能。查看我更新的错误消息代码,以及更好地查看我的应用程序的一些类和页面
  • @JNate 更新了我的答案,您需要使用 {StaticResource Locator} 而不仅仅是 Locator(否则它将源绑定到字符串 Locator 而不是 Locator 资源
  • 成功了!!非常感谢!!我设法让 TileshomeView 出现和消失,但是我注意到当瓷砖重新出现时,它不会再显示瓷砖内的数据。我的 hubtiles 是使用 windows phone 工具包创建的。你认为我做错了什么?你认为我应该在每次调用图块时调用一个函数来重新加载数据吗?
  • 通常你不需要调用任何“reload”方法,你是在tile里面绑定数据吗?如果不是,您如何填写数据?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-17
  • 2014-07-28
  • 2011-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多