9

我正在尝试将 Window Title 绑定到具有 Title 属性的 ViewModel。下面是 MainWindow XAML:

<Window x:Class="MyProject.View.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:MyProject.ViewModel;assembly=MyProject.ViewModel"
        Title="{Binding Path=Title}" Height="350" Width="525" DataContext="{Binding Source={StaticResource mainWindowViewModel}}">
    <Window.Resources>
        <vm:MainWindow x:Key="mainWindowViewModel"/>
    </Window.Resources>

...

</Window>

当我尝试运行它时,我得到以下异常“在'System.Windows.StaticResourceExtension'上提供值引发异常。行号和位置指向DataContext属性,内部异常状态“找不到名为mainWindowViewModel的资源。

下面是视图模型的代码:

namespace MyProject.ViewModel
{
    public class MainWindow : INotifyPropertyChanged
    {
        #region Fields

        private const string TitlebarPrefixString = "My Project";
        private string title = TitlebarPrefixString;

        public string Title {
            get
            {
                return this.title;
            } // End getter
            set
            {    
                this.title = value;
                OnPropertyChanged("Title");
            } // End setter
        } // End property

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            } // End if
        } // End method


        public event PropertyChangedEventHandler PropertyChanged;

    } // End class
} // End namespace

我的理论是在尝试将标题绑定到属性之后加载资源。引发异常时,Window 的 Resources 属性为空。

在后面的代码中设置 DataContext 是唯一的解决方案吗?我可以让它工作,但我更愿意将它保存在 XAML 中。

4

2 回答 2

13

您可以尝试设置DataContextusing 属性元素语法:

<Window x:Class="MyProject.View.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vm="clr-namespace:MyProject.ViewModel;assembly=MyProject.ViewModel"
    Title="{Binding Path=Title}" Height="350" Width="525">
<Window.Resources>
    <vm:MainWindow x:Key="mainWindowViewModel"/>
</Window.Resources>
<Window.DataContext>
  <StaticResourceExtension ResourceKey="mainWindowViewModel"/>
</Window.DataContext>

这应该可以工作,因为 xaml 解析器将StaticResourceExtension在设置资源字典后执行。

但我认为直接设置 DataContext 可能更好,而不将其声明为资源:

<Window x:Class="MyProject.View.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vm="clr-namespace:MyProject.ViewModel;assembly=MyProject.ViewModel"
    Title="{Binding Path=Title}" Height="350" Width="525">
<Window.DataContext>
    <vm:MainWindow x:Key="mainWindowViewModel"/>
</Window.DataContext>
于 2013-06-05T16:37:17.483 回答
0

有点晚了,但我正在使用一个简单而完美的解决方案,以防人们仍在寻找可能性:

<Window x:Class="Project.MainWindow"
        Title="{Binding DataContext.ApplicationTitle, ElementName=TheMainView}">

        <views:MainView x:Name="TheMainView"/>

</Window>

很简单,只需向 MainViewModel 添加一个属性,即 MainView 的 DataContext,如下所示:

public string ApplicationTitle
        {
            get
            {
                var text = "Application Name";
                if (!string.IsNullOrEmpty(_currentFileLoaded))
                {
                    text += $" ({_currentFileLoaded})";
                }

                return text;
            }
        }

希望能帮助到你..

于 2017-02-28T18:07:34.577 回答