WPF Bind Window Title to ViewModel Property

18,033

You can try to set the DataContext using property element syntax:

<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 StaticResourceExtension after the resources dictionary is set.

But i think maybe even better would be to set the DataContext directly, without declaring it as resource:

<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>
Share:
18,033

Related videos on Youtube

Tim
Author by

Tim

Updated on June 04, 2022

Comments

  • Tim
    Tim almost 2 years

    I am trying to bind a Window Title to the ViewModel which has a Title property. Below is the 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.

    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.

    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.

    • Viv
      Viv almost 11 years
      you could always move your VM resource to app.xaml if that's applicable. On a sidenote please name VM classes as SomethingViewModel and not just the same name as the View and use namespace to differentiate classes. It's just really weird and freaky
  • Tim
    Tim almost 11 years
    Your first suggestion throws the same exception. Interestingly enough, the Window shows the resource in the Locals view when I use Break. The second suggestion gives three compile-time errors: "The "Key" attribute can only be used on an element that is contained in IDictionary"; "Key attribute can by used only on a tag contained in an IDictionary type property" and "The Key attribute can only be used on a tag contained in a Dictionary (such as a ResourceDictionary"
  • Jurica Smircic
    Jurica Smircic almost 11 years
    @Tim I made an error in the ResourceKey="mainWindowModel".. it should state ResourceKey="mainWindowViewModel" . If you only copy-pasted try to correct it. But im not really sure about this, i think once i got it to work like that.
  • Tim
    Tim almost 11 years
    That fixed it, which is really good news. I am revisiting this question, because I am having difficulty with referencing the view model declared programmatically, so making it pure XAML again may help my other issue.
  • user2023861
    user2023861 over 9 years
    @jure your suggestion helped me with a somewhat related problem. I wanted to set the Window title to a Binding with a Path and a Converter. I defined the Converter in <Window.Resources>, but setting the binding in the <Window> threw an exception because it doesn't yet have access to the <Window.Resources>. Setting the Window Title the way you suggested was an easy workaround. Thanks.