2013-06-05 15 views
9

Próbuję powiązać tytuł okna z obiektem ViewModel, który ma właściwość Tytuł. Poniżej znajduje się MainWindow XAML:Tytuł okna powiązania pliku WPF do właściwości 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> 

Kiedy próbuję uruchomić to pojawia się następujący wyjątek „Podaj wartość na«System.Windows.StaticResourceExtension»zwrócił wyjątek numer linii i pozycja kropki do właściwości DataContext. , a wewnętrzny wyjątek stwierdza "Nie można znaleźć zasobu o nazwie mainWindowViewModel.

Poniżej znajduje się kod dla widoku modelu:

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 

Moja teoria jest taka, że ​​zasoby są ładowane po próbie związania tytuł do nieruchomości. Po wygenerowaniu wyjątku właściwość Resources dla okna jest pusta.

Czy jedynym rozwiązaniem jest ustawienie DataContext w polu Behind? Mogę to uruchomić, ale wolałbym zachować go w XAML.

+2

zawsze możesz przenieść swój VM do pliku app.xaml, jeśli to ma zastosowanie. W sidenote nazwij klasy VM jako 'SomethingViewModel', a nie tylko tę samą nazwę, co przestrzeń View i use, aby rozróżnić klasy. To jest po prostu dziwne i dziwaczne – Viv

+0

Josh Smith miał przykład tego, zobaczę, czy mogę go zlokalizować, w zasadzie, gdy datatemplate został zastosowany w XAML, tytuł został zastosowany też. –

Odpowiedz

12

Można spróbować ustawić za pomocą elementu składni DataContext nieruchomości:

<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> 

To powinno działać jak parser XAML wykona StaticResourceExtension po słownika zasobów jest ustawiony.

Ale myślę, że może nawet lepiej byłoby ustawić DataContext bezpośrednio, bez deklarowania go jako zasób:

<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

Twoja pierwsza sugestia rzuca ten sam wyjątek. Co ciekawe, okno pokazuje zasób w widoku Lokali, gdy używam Przerwa. Druga sugestia daje trzy błędy podczas kompilacji: "Atrybut" Klucz "może być użyty tylko na elemencie zawartym w IDictionary"; "Atrybut kluczowy może być użyty tylko na znaczniku zawartym we właściwości typu IDictionary" i "Atrybut Klucza może być użyty tylko na znaczniku zawartym w słowniku (takim jak ResourceDictionary" – Tim

+1

@ Tim Zrobiłem błąd w ResourceKey = "mainWindowModel" ... powinien podać ResourceKey = "mainWindowViewModel" .Jeśli tylko skopiowałeś-wklejony spróbuj go poprawić.Ale nie jestem do końca tego pewien, myślę, że kiedyś udało mi się go uruchomić. – jure

+0

To naprawiło to, co to naprawdę dobra wiadomość. Wracam do tego pytania, ponieważ mam trudności z odniesieniem się do modelu widoku zadeklarowanego programowo, więc sprawienie, że będzie to czysty XAML, może ponownie pomóc w moim drugim wydaniu – Tim

0

Trochę późno, ale proste i idealne rozwiązanie, że używam tylko w przypadku ludzi są nadal poszukiwanie możliwości:

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

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

</Window> 

niż wystarczająco prosto, wystarczy dodać obiekt do swojej MainViewModel która jest DataContext z MAINVIEW tak:

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

       return text; 
      } 
     } 

Mam nadzieję, że pomoże ..

Powiązane problemy