2012-12-31 225 views
5

我試圖用ResourceDictionary中的ViewModel綁定視圖,但它不起作用。WPF與ResourceDictionary的MVVM數據綁定MVVM

該應用程序是非常簡單的窗口與2個文本框。當我將文本鍵入textbox1時,textbox2必須獲取相同的文本。當然,我的視圖中的文本框必須綁定到ViewModel中的屬性。

我新的WPF,我開始綁定視圖和的ViewModels的方式是在視圖的代碼隱藏:

DataContext = new MyViewModel(); 

現在我想要實現一個更清潔的分離。我的代碼是

的App.xaml:

<Application x:Class="NavigationCleanBinding.App" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     StartupUri="/Views/MainWindowView.xaml"> 
    <Application.Resources> 
     <ResourceDictionary Source="MainResourceDictionary.xaml" /> 
    </Application.Resources> 
</Application> 

MainResourceDictionary.xaml:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xamlpresentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:Views="clr-namespace:NavigationCleanBinding.Views" 
    xmlns:ViewModels="clr-namespace:NavigationCleanBinding.ViewModels"> 

    <DataTemplate DataType="{x:Type ViewModels:MainWindowViewModel}"> 
     <Views:MainWindowView /> 
    </DataTemplate> 

</ResourceDictionary> 

MainWindowView.xaml:

<Window x:Class="NavigationCleanBinding.Views.MainWindowView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525"> 

<Grid> 
    <TextBox Height="23" HorizontalAlignment="Left" Margin="61,14,0,0" 
      Name="textBox1" VerticalAlignment="Top" Width="120" 
      Text="{Binding TestData, Mode=TwoWay, 
      UpdateSourceTrigger=PropertyChanged}"/> 
    <Label Content="Test:" Height="28" HorizontalAlignment="Left" Margin="12,12,0,0" 
     Name="label1" VerticalAlignment="Top" Width="43" /> 
    <Label Content="Result:" Height="28" HorizontalAlignment="Left" Margin="10,46,0,0" 
     Name="label2" VerticalAlignment="Top" /> 

    <TextBox Height="23" HorizontalAlignment="Left" Margin="61,48,0,0" 
      Name="textBox2" VerticalAlignment="Top" Width="120" 

      Text="{Binding TestData, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/> 
    </Grid> 
</Window> 

MainWindowViewModel:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace NavigationCleanBinding.ViewModels 
{ 
    class MainWindowViewModel 
    { 
     private String _testData; 
     public String TestData 
     { 
      get { return _testData; } 
      set { _testData = value; } 
     } 

     private MainWindowViewModel() 
     { 
      _testData = null; 
     } 
    } 
} 

UPDATE:

我改變屬性TESTDATA這樣:

public String TestData 
    { 
     get { return _testData; } 
     set 
     { 
      _testData = value; 
      OnPropertyChanged("TestData"); 

     } 
    } 

而且implemened的INotifyPropertyChanged的是這樣的:

public event PropertyChangedEventHandler PropertyChanged; 
    private void OnPropertyChanged(String propertyName) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
+0

您是否在輸出窗口中看到任何錯誤? – Thelonias

+0

沒有錯誤,沒有警告。它只是不起作用。 – shadox

+0

我不認爲你的DataContext正在爲你的'MainWindowView'設置。我認爲,「MainWindowViewModel」是「MainResourceDictionary」的DataContext。因爲你的StartupURI設置爲MainWindowView,它會創建你的Window的一個實例,但是不會設置DataContext。我不積極,但我不認爲你的ResourceDictionary在這一點上做了什麼。 – Thelonias

回答

4

所以user1064 519是在正確的軌道上:

  • 查看需要一個UserControl,而不是一個Window,因爲它是在主窗口
  • 視圖模型需要被加載到主窗口託管,這是什麼觸發要發現並加載DataTemplate

    <Window x:Class="WpfTemplateBootstrap.MainWindow" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:local="clr-namespace:WpfTemplateBootstrap" 
        Title="MainWindow" Height="350" Width="525"> 
        <ContentControl> 
         <ContentControl.Content> 
          <local:MainWindowViewModel /> 
         </ContentControl.Content> 
        </ContentControl> 
    

之後,你應該是啓動和運行。 我已經在這裏發佈了一個深入的示例:wpf bootstrapping datatemplates--the chicken and the egg

+0

我認爲TheZenker在他的博客上的響應非常好,並且鏈接到此處。 – shadox

1

您的視圖模型必須實現的接口INotifyPropertyChanged並提出一個PropertyChanged事件時任何綁定的屬性值都會更改,以便您的視圖可以知道發生的更改。

+0

它仍然不起作用...我的一位朋友建議指定RelativeSource ...關於祖先的事情...我實際上不明白。 – shadox

1

DataTemplate sholudnt包含窗口,它可以包含任何類型的控件。

的DataTemplate:

<DataTemplate DataType="{x:Type ViewModels:MainWindowViewModel}"> 
     <Views:MainWindowView /> 
</DataTemplate> 

用戶控件:

<UserControl x:Class="NavigationCleanBinding.Views.MainView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Height="350" Width="525"> 

<Grid> 
    <TextBox Height="23" HorizontalAlignment="Left" Margin="61,14,0,0" 
      Name="textBox1" VerticalAlignment="Top" Width="120" 
      Text="{Binding TestData, Mode=TwoWay, 
      UpdateSourceTrigger=PropertyChanged}"/> 
    <Label Content="Test:" Height="28" HorizontalAlignment="Left" Margin="12,12,0,0" 
     Name="label1" VerticalAlignment="Top" Width="43" /> 
    <Label Content="Result:" Height="28" HorizontalAlignment="Left" Margin="10,46,0,0" 
     Name="label2" VerticalAlignment="Top" /> 

    <TextBox Height="23" HorizontalAlignment="Left" Margin="61,48,0,0" 
      Name="textBox2" VerticalAlignment="Top" Width="120" 

      Text="{Binding TestData, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/> 
    </Grid> 
</UserControl> 

窗口:

<Window x:Class="NavigationCleanBinding.Views.MainWindowView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525"> 

<ContentControl Content={Binding}/> 
</Window> 
+0

其實它不工作...你可以告訴我你的app.xaml?並請說明主窗口如何綁定到mai主視圖UserControl。謝謝! – shadox

+0

您的UserControl如何瞭解DataTemplate?如果它在某些ResourceDictionary中,UserControl應該知道它,對嗎? –

+0

您可以將它放在資源字典或window.resources或app.resources中,這取決於您的需求 – user1064519