0

データ オブジェクトにバインドされた Textbox があります。検証が失敗した場合、エラー メッセージを含むポップアップを表示したいと思います。XAML では、これは正常に機能します。次の XAML を使用しています。

<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);
4

2 に答える 2

0

また、簡単な解決策を作成し、コードをコピーしましたが、問題なく実行されました。KentはポップアップをXAMLで宣言しましたが、ポップアップの作成とバインディングの設定に正確なコードを使用したので、違いが問題の原因にならないようにする必要があります。

ソース変数がどこから来ているのか投稿していただけませんか。あなたはそれを示さない、そして私はそれがあなたがそれであると思うものであるかどうか疑問に思う。

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

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

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;
            }
        }
    }
于 2009-03-03T11:40:23.837 に答える