WPF 将窗口标题绑定到 ViewModel 属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16945198/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF Bind Window Title to ViewModel Property
提问by Tim
I am trying to bind a Window Title to the ViewModel which has a Title property. Below is the MainWindow XAML:
我正在尝试将窗口标题绑定到具有 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>
When I try to run this, I get the following exception "Provide value on 'System.Windows.StaticResourceExtension' threw an exception. The line number and position point to the DataContext property, and the inner exception states "Cannot find resource named mainWindowViewModel.
当我尝试运行它时,我收到以下异常“在 'System.Windows.StaticResourceExtension' 上提供值抛出异常。行号和位置指向 DataContext 属性,并且内部异常状态”无法找到名为 mainWindowViewModel 的资源。
Below is the code for the View Model:
下面是视图模型的代码:
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
My theory is that the resources are loaded after the attempt to bind the title to the property. When the exception is thrown, the Resources property for the Window is empty.
我的理论是在尝试将标题绑定到属性后加载资源。引发异常时,Window 的 Resources 属性为空。
Is the only solution to set the DataContext in the Code Behind? I can get this to work, but I would prefer to keep it in XAML.
是在代码隐藏中设置 DataContext 的唯一解决方案吗?我可以让它工作,但我更愿意将它保留在 XAML 中。
回答by jure
You can try to set the DataContextusing property element syntax:
您可以尝试设置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>
That should work as the xaml parser will execute StaticResourceExtensionafter the resources dictionary is set.
这应该可以工作,因为 xaml 解析器将StaticResourceExtension在设置资源字典后执行。
But i think maybe even better would be to set the DataContext directly, without declaring it as resource:
但我认为直接设置 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>
回答by Eibi
A little late but a simple and perfect solution that I am using just in case people are still searching for possibilities:
有点晚了,但我正在使用一个简单而完美的解决方案,以防万一人们仍在寻找可能性:
<Window x:Class="Project.MainWindow"
Title="{Binding DataContext.ApplicationTitle, ElementName=TheMainView}">
<views:MainView x:Name="TheMainView"/>
</Window>
Than simply enough, just add a Property to your MainViewModel that is the DataContext of the MainView like so:
不仅如此,只需向 MainViewModel 添加一个属性,即 MainView 的 DataContext,如下所示:
public string ApplicationTitle
{
get
{
var text = "Application Name";
if (!string.IsNullOrEmpty(_currentFileLoaded))
{
text += $" ({_currentFileLoaded})";
}
return text;
}
}
Hope it helps..
希望能帮助到你..

