2009-03-03 31 views
0

私のデータオブジェクトにバインドされたテキストボックスがあります。検証に失敗した場合は、エラーメッセージを含むポップアップを表示したいと思います。 XAMLではうまく動作します。私は、次のXAMLを使用しています:コード内のPopup.IsOpenをValidation.HasErrorにバインドする方法

<TextBox Height="23" Margin="54,12,104,0" Name="textBox1" 
VerticalAlignment="Top" Text="{Binding Value, ValidatesOnExceptions=True, UpdateSourceTrigger=PropertyChanged}"></TextBox> 

     <Popup Name="myPopup" PlacementTarget="{Binding ElementName=textBox1}" 
         IsOpen="{Binding ElementName=textBox1, Path=(Validation.HasError), Mode=OneWay}" 
         > 
      <TextBlock Name="myPopupText" Background="LightBlue" Foreground="Blue"> 
         The value is invalid 
      </TextBlock> 
     </Popup> 

私の問題は、私は、ポップアップを作成する必要があり、コードに結合し、私はそれが仕事を得ることができないということです。私はいくつかの異なるオプションを試しました。私はバインディングが全く機能するかどうかを見るためにダミーコンバータも使用しました。それは私がそれを(それは初期値を取得する)を作成するときにバインディングが動作するようだが、その後何も起こりません。 Validation.HasErrorが正しく更新されていることがわかります(TextBoxの枠線が赤く変わります)が、それだけです。私のダミーコンバータは呼び出されません。以下は、私が使用しているコードです:

Popup popup = new Popup(); 
    popup.Name = "somepopup"; 
    // Source is the textbox which is bound to the data object 
    popup.PlacementTarget = source; 
    popup.Placement = PlacementMode.Bottom; 
    TextBlock txtblock = new TextBlock(); 
    txtblock.Background = Brushes.LightBlue; 
    txtblock.Foreground = Brushes.Blue; 
    txtblock.Text = "this is the error message"; 
    popup.Child = txtblock; 

    Binding is_open_binding = new Binding("(Validation.HasError)"); 
    is_open_binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; 
    is_open_binding.Source = source; 
    is_open_binding.Mode = BindingMode.OneWay; 
    is_open_binding.NotifyOnValidationError = true; 
    is_open_binding.ValidatesOnExceptions = true; 
    is_open_binding.Converter = new TempValueConverter(); 
    popup.SetBinding(Popup.IsOpenProperty, is_open_binding); 

答えて

3

ちょうど簡単なテストを行い、うまくいきました。ここに私のXAMLは次のとおりです。

<Window x:Name="_root" x:Class="WpfApplication1.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300"> 
    <StackPanel> 
     <TextBox x:Name="_textBox"> 
      <TextBox.Text> 
       <Binding Path="Text" ElementName="_root" UpdateSourceTrigger="PropertyChanged"> 
        <Binding.ValidationRules> 
         <ExceptionValidationRule/> 
        </Binding.ValidationRules> 
       </Binding> 
      </TextBox.Text> 
     </TextBox> 
     <!--<Popup x:Name="_popup" IsOpen="{Binding (Validation.HasError), ElementName=_textBox, Mode=OneWay}">--> 
     <Popup x:Name="_popup"> 
      <Border BorderThickness="1" BorderBrush="Black" Background="White"> 
       <TextBlock>Here I am.</TextBlock> 
      </Border> 
     </Popup> 
    </StackPanel> 
</Window> 

そしてここでは、コードビハインドである:

using System; 
using System.Windows; 
using System.Windows.Controls.Primitives; 
using System.Windows.Data; 

namespace WpfApplication1 
{ 
    public partial class Window1 : Window 
    { 
     public string Text 
     { 
      get { return "Text"; } 
      set { if (value != "Text") throw new InvalidOperationException("Bla"); } 
     } 

     public Window1() 
     { 
      InitializeComponent(); 

      var binding = new Binding("(Validation.HasError)"); 
      binding.Source = _textBox; 
      binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; 
      binding.Mode = BindingMode.OneWay; 
      binding.NotifyOnValidationError = true; 
      binding.ValidatesOnExceptions = true; 
      //binding.Converter = new TempValueConverter(); 
      _popup.SetBinding(Popup.IsOpenProperty, binding); 
     } 

     private sealed class TempValueConverter : IValueConverter 
     { 
      #region IValueConverter Members 

      public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
      { 
       throw new NotImplementedException(); 
      } 

      public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
      { 
       throw new NotImplementedException(); 
      } 

      #endregion 
     } 
    } 
} 
0

また、私は簡単な解決策を作り、あなたのコードにコピーし、それがうまく走りました。ケントはXAMLで宣言したポップアップを持っていましたが、ポップアップを作成してバインドを設定するためのコードを使用しました。その違いが問題の原因ではないはずです。

ソース変数がどこから来たのか投稿できるかどうかは疑問です。あなたはそれを示していないし、それがあなたの考えであるかどうか疑問に思います。

あなたが試みるかもしれない別のことは、ガベージコレクションされている周りのポップアップへの参照を保持することです。私は、バインディングがポップアップインスタンスへの永続的なリンクにならないように、変更通知用の週イベントハンドラを正しく使用しているかのように、これが可能であると考えています。しかし、これは起こりそうもないと思いますが、一発の価値があるかもしれません。

FYIこれをテストするために使用したコードは次のとおりです。

XAMLファイル:

<Window x:Class="PopupOpenBindingTest.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" 
    Height="300" 
    Width="300"> 
<Grid> 
    <TextBox Height="23" 
      Margin="54,12,104,0" 
      Name="textBox1" 
      VerticalAlignment="Top" 
      Text="{Binding Text, ValidatesOnExceptions=True, UpdateSourceTrigger=PropertyChanged}" /> 
</Grid></Window> 

コードビハインド。

public partial class Window1 : Window 
{ 
    public Window1() 
    { 
     InitializeComponent(); 

     DataContext = new DataObjectTest(); 
     this.Loaded += new RoutedEventHandler(Window1_Loaded); 
    } 

    void Window1_Loaded(object sender, RoutedEventArgs e) 
    { 
     TextBox source = textBox1; 

     Popup popup = new Popup(); 
     popup.Name = "somepopup"; 
     popup.PlacementTarget = source; 
     popup.Placement = PlacementMode.Bottom; 
     TextBlock txtblock = new TextBlock(); 
     txtblock.Background = Brushes.LightBlue; 
     txtblock.Foreground = Brushes.Blue; 
     txtblock.Text = "this is the error message"; 
     popup.Child = txtblock; 
     Binding is_open_binding = new Binding("(Validation.HasError)");// { Path = new PropertyPath(Validation.HasErrorProperty) }; 
     is_open_binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; 
     is_open_binding.Source = source; 
     is_open_binding.Mode = BindingMode.OneWay; 
     is_open_binding.NotifyOnValidationError = true; 
     is_open_binding.ValidatesOnExceptions = true; 
     //is_open_binding.Converter = new TempValueConverter(); 
     popup.SetBinding(Popup.IsOpenProperty, is_open_binding); 
    } 

    public class DataObjectTest 
    { 
     private string _text = string.Empty; 

     public string Text 
     { 
      get { return _text; } 
      set 
      { 
       if (value.Length > 5) 
        throw new InvalidOperationException("Blah blah blah"); 

       _text = value; 
      } 
     } 
    } 
関連する問題