2017-01-18 10 views
0

MVVMデザインパターンを使用して簡単な検証を実装しようとしているビュー内に2つのテキストボックスがあります。 ViewModelはInotification Changedインターフェイスを実装しています。プロパティはTextBoxのtextプロパティにバインドされています。propertyChangeイベントは発生しません。どこが間違っているのか分かりません。助けてください。テキストが変更されたり、テキストボックス内のテキストボックスに挿入されたときに "PropertyChange"が起動しない

のViewModel:

class TextBoxValidationViewModel : ViewModelBase, IDataErrorInfo 
    { 
     private readonly TextBoxValidationModel _textbxValModel; 
     private Dictionary<string, bool> validProperties; 
     private bool allPropertiesValid = false; 

     private DelegateCommand exitCommand; 
     private DelegateCommand saveCommand; 

     public TextBoxValidationViewModel(TextBoxValidationModel newTextBoxValObj) 
     { 
      this._textbxValModel = newTextBoxValObj; 
      this.validProperties = new Dictionary<string, bool>(); 
      this.validProperties.Add("BuyTh", false); 
      this.validProperties.Add("SellTh", false); 


     } 


     public string BuyTh 
     { 
      get { return _textbxValModel.BuyTh; } 
      set 
      { 
       if (_textbxValModel.BuyTh != value) 
       { 
        _textbxValModel.BuyTh = value; 
        base.OnPropertyChanged("BuyTh"); 
       } 
      } 
     } 

     public string SellTh 
     { 
      get { return _textbxValModel.SellTh; } 
      set 
      { 
       if (_textbxValModel.SellTh != value) 
       { 
        _textbxValModel.SellTh = value; 
        base.OnPropertyChanged("SellTh"); 
       } 
      } 
     } 



     public bool AllPropertiesValid 
     { 
      get { return allPropertiesValid; } 
      set 
      { 
       if (allPropertiesValid != value) 
       { 
        allPropertiesValid = value; 
        base.OnPropertyChanged("AllPropertiesValid"); 
       } 
      } 
     } 


     public string this[string propertyName] 
     { 
      get 
      { 
       string error = (_textbxValModel as IDataErrorInfo)[propertyName]; 
       validProperties[propertyName] = String.IsNullOrEmpty(error) ? true : false; 
       ValidateProperties(); 
       CommandManager.InvalidateRequerySuggested(); 
       return error; 
      } 
     } 

     public string Error 
     { 
      get 
      { 
       return (_textbxValModel as IDataErrorInfo).Error; 
      } 
     } 

     public ICommand ExitCommand 
     { 
      get 
      { 
       if (exitCommand == null) 
       { 
        exitCommand = new DelegateCommand(Exit); 
       } 
       return exitCommand; 
      } 
     } 

     public ICommand SaveCommand 
     { 
      get 
      { 
       if (saveCommand == null) 
       { 
        saveCommand = new DelegateCommand(Save); 
       } 
       return saveCommand; 
      } 
     } 



     #region private helpers 

     private void ValidateProperties() 
     { 
      foreach (bool isValid in validProperties.Values) 
      { 
       if (!isValid) 
       { 
        this.AllPropertiesValid = false; 
        return; 
       } 
      } 
      this.AllPropertiesValid = true; 
     } 

     private void Exit() 
     { 
      Application.Current.Shutdown(); 
     } 


     private void Save() 
     { 
      _textbxValModel.Save(); 
     } 

    } 

} 
#endregion 

モデル:

class TextBoxValidationModel : IDataErrorInfo 
    { 

     public string BuyTh { get; set; } 
     public string SellTh { get; set; } 

     public void Save() 
     { 
      //Insert code to save new Product to database etc 
     } 

     public string this[string propertyName] 
     { 
      get 
      { 
       string validationResult = null; 
       switch (propertyName) 
       { 
        case "BuyTh": 
         validationResult = ValidateName(); 
         break; 
        case "SellTh": 
         validationResult = ValidateName(); 
         break; 

        default: 
         throw new ApplicationException("Unknown Property being validated on Product."); 
       } 
       return validationResult; 
      } 
     } 

     public string Error 
     { 
      get 
      { 
       throw new NotImplementedException(); 
      } 
     } 


     private string ValidateName() 
     { 

      return "Entered in validation Function"; 
     } 
    } 
} 

ViewModelBase抽象クラス:

public abstract class ViewModelBase : INotifyPropertyChanged 
    { 
     public event PropertyChangedEventHandler PropertyChanged; 

     protected void OnPropertyChanged(string propertyName) 
     { 
      PropertyChangedEventHandler handler = PropertyChanged; 

      if (handler != null) 
      { 
       handler(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
    } 
} 

アプリケーションの起動イベントコード:

private void Application_Startup(object sender, StartupEventArgs e) 
     { 
      textboxvalwpf.Model.TextBoxValidationModel newTextBoxValObj = new Model.TextBoxValidationModel(); 
      TextBoxValidation _txtBoxValView = new TextBoxValidation(); 
      _txtBoxValView.DataContext = new textboxvalwpf.ViewModel.TextBoxValidationViewModel(newTextBoxValObj); 
     //  _txtBoxValView.Show(); 

     } 
    } 

XAMLコードビュー:App.xamlで

<Window x:Class="textboxvalwpf.TextBoxValidation" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:c="clr-namespace:textboxvalwpf.Commands" 
     xmlns:local="clr-namespace:textboxvalwpf" 
     mc:Ignorable="d" 
     Title="TextBoxValidation" Height="300" Width="300"> 
    <Grid> 
     <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="86,44,0,0" TextWrapping="Wrap" Text="{Binding Path=BuyTh, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120"/> 
     <TextBox x:Name="textBox1" HorizontalAlignment="Left" Height="23" Margin="88,121,0,0" TextWrapping="Wrap" Text="{Binding Path=SellTh,ValidatesOnDataErrors=True,UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120"/> 
     <Label x:Name="label_BuyTh" Content="Buy Th" HorizontalAlignment="Left" Margin="10,44,0,0" VerticalAlignment="Top" Width="71"/> 
     <Label x:Name="label_SellTh" Content="Sell Th" HorizontalAlignment="Left" Margin="10,117,0,0" VerticalAlignment="Top" Width="71"/> 

    </Grid> 
</Window> 
+0

だろう高く評価される。 – AlphaWarrior

+0

あなたはウィンドウを表示する行をコメントアウトしました。それは2つのウィンドウが表示されていたからですか? –

+0

@EdPlunkett:そうです。 – AlphaWarrior

答えて

0

、あなたはStartupUri属性を見つけることができます。デフォルトでは、次のようになります。

<Application x:Class="WPFTest.App" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:local="clr-namespace:WPFTest" 
      StartupUri="MainWindow.xaml"> 

あなたはTextBoxValidation.xamlにMainWindow.xamlの名前を変更した場合、私はあなたがたと思うと、それは次のようになります:

   StartupUri="TextBoxValidation.xaml"> 

アプリケーションは自動的にそのStartupUriウィンドウのインスタンスを作成して表示します。それがアプリケーションのメインウィンドウになるので、アプリケーションは終了時にシャットダウンします。

このインスタンスにはビューモデルがありません。コード内には何も表示されないためです。ウィンドウの独自のインスタンスを作成し、ビューモデルを与えた後、別のインスタンスが表示されているので、何もしません。私はあなたがウィンドウを作成するだけでそれを示すのに十分だと思ったと思うが、それはまったく起こっていない。 Show()呼び出しをコメントアウトする前に、検証を行い、viewmodelプロパティを更新した作業ビューモデルを持つウィンドウが1つありました。

Appが望むようにウィンドウを作成させます。

素早く、簡単な修正はAppからそのStartupイベントハンドラを削除し、TextBoxValidationのコンストラクタにあなたのviewmodel作成コードを移動することです:誰でもすぐにこれらのコードblocks.Thatに見ていることができれば

public TextBoxValidation() 
{ 
    InitializeComponent(); 

    textboxvalwpf.Model.TextBoxValidationModel newTextBoxValObj = new Model.TextBoxValidationModel(); 

    this.DataContext = new textboxvalwpf.ViewModel.TextBoxValidationViewModel(newTextBoxValObj); 
} 
+0

ありがとうございます。これは今修正されました。 – AlphaWarrior

関連する問題