WPF绑定窗口标题到ViewModel属性
本文关键字:ViewModel 属性 窗口标题 绑定 WPF | 更新日期: 2023-09-27 18:17:17
我试图将窗口标题绑定到具有Title属性的ViewModel。下面是主窗口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属性,内部异常状态为"Cannot find resource named 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。
您可以尝试使用属性元素语法设置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.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>
有点晚了,但我正在使用一个简单而完美的解决方案,以防人们仍在寻找可能性:
<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;
}
}