2012-12-31 54 views
5

ViewをResourceDictionary内のViewModelでバインドしようとしていますが、機能しません。ResourceDictionaryでのWPFデータバインディング

アプリケーションは2つのテキストボックスを持つ非常に単純なウィンドウです。 textbox1にテキストを入力すると、自動的にtextbox2は同じテキストを取得する必要があります。もちろん、Viewからの私のテキストボックスは、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"); 

     } 
    } 

そして、このようにINotifyPropertyChangedのをimplemened:

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です。 MainWindowViewにStartupURIが設定されているため、Windowのインスタンスが作成されますが、DataContextは決して設定されません。私は肯定的ではありませんが、ResourceDictionaryがこの時点で何もしていないと思います。 – Thelonias

答えて

4

のでuser1064 519は正しい軌道に乗っていた:それはメインウィンドウでホストされているよう

  • ビューはViewModelには、これが引き金何で、メインウィンドウにロードする必要があります
  • 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

あなたのViewModelはインターフェイス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を見せてくれますか?そしてメインウィンドウがUserControlをメインビューにバインドする方法を説明してください。ありがとう! – shadox

+0

UserControlがDataTemplateについてどのように知っていますか?そしてそれがいくつかのResourceDictionaryにある場合、UserControlはそれについて知っているはずですよね? –

+0

リソースディクショナリまたはwindow.resourcesまたはapp.resourcesのどちらかに置くことができます。これはニーズに応じて異なります。 – user1064519

関連する問題