2013-06-05 3 views
9

Я пытаюсь связать заголовок окна с ViewModel, у которого есть свойство Title. Ниже MainWindow XAML:WPF Bind Window Title to ViewModel Свойство

<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 

Моя теория состоит в том, что ресурсы загружаются после попытки связать право собственности на имущество. Когда выбрано исключение, свойство Resources для Window пусто.

является единственным решением, чтобы установить DataContext в код? Я могу заставить это работать, но я бы предпочел сохранить его в XAML.

+2

Вы всегда можете переместить свой ресурс VM на app.xaml, если это применимо. В боковом названии, пожалуйста, назовите классы VM как «SomethingViewModel», а не просто то же имя, что и пространство имен «Просмотр» и «Использование», чтобы различать классы. Это просто очень странно и причудливо – Viv

+0

Джош Смит пример этого я буду видеть, если я могу найти его, в основном, когда DataTemplate был применен в XAML название было применено слишком .. –

ответ

12

Вы можете попробовать установить синтаксис элемента 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> 
+0

Ваше первое предложение бросками же исключение. Интересно, что окно показывает ресурс в представлении «Локали», когда я использую Break. Второе предложение дает три ошибки времени компиляции: «Атрибут« Ключ »может использоваться только для элемента, содержащегося в IDictionary»; «Ключевой атрибут может использоваться только для тега, содержащегося в свойстве типа IDictionary» и «Атрибут« Ключ »может использоваться только в теге, содержащемся в словаре (например, в ResourceDictionary» – Tim

+1

@Tim Я сделал ошибку в ResourceKey = «mainWindowModel» .. это должно быть указано ResourceKey = «mainWindowViewModel». Если вы только копировать-вставить попытку исправить. Но им не совсем уверен в этом, я думаю, как только я получил его на работу, как это. – jure

+0

это зафиксировал его, что это действительно хорошая новость. Я пересматриваю этот вопрос, потому что у меня возникают трудности с ссылкой на модель представления, объявленной программно, поэтому сделать ее чистым XAML снова может помочь в моей другой проблеме. – Tim

0

Немного поздно, но простой и отличное решение, что я использую только в случае, если люди по-прежнему поиске возможностей:

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

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

</Window> 

чем достаточно просто, просто добавить свойство к вашему MainViewModel, который является DataContext в MainView так:

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

       return text; 
      } 
     } 

Надеюсь, что это поможет.