2013-06-05 135 views
9

我試圖將窗口標題綁定到具有Title屬性的ViewModel。下面是主窗口XAML:WPF將窗口標題綁定到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 

我的理論是,資源的標題綁定到該屬性的嘗試後加載。拋出異常時,Window的Resources屬性爲空。

在代碼背後設置DataContext的唯一解決方案?我可以得到這個工作,但我寧願保留在XAML中。

+2

如果適用,您可以隨時將您的虛擬機資源移動到app.xaml。在旁註中,請將VM類命名爲「SomethingViewModel」,而不僅僅是與View相同的名稱,並使用命名空間來區分類。這只是非常奇怪和怪異的 – Viv

+0

喬希史密斯有一個這樣的例子,我會看看如果我可以找到它,基本上當數據模板應用在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時,Window顯示Locals視圖中的資源。第二個建議給出了三個編譯時錯誤:「」Key「屬性只能用於包含在IDictionary中的元素」; 「Key屬性只能用於包含在IDictionary類型屬性中的標籤」和「Key屬性只能用於包含在Dictionary中的標籤(比如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那是的MainView的,像這樣的DataContext:

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

       return text; 
      } 
     } 

希望它有幫助..

相關問題