【问题标题】:WPF Binding: disable TextBoxes + Validation and DataContext IssueWPF 绑定:禁用 TextBoxes + 验证和 DataContext 问题
【发布时间】:2018-06-13 10:22:16
【问题描述】:

我的简单程序有两个窗口:

  • 从第一个我设置了一个Boolean 值,然后...
  • 我将在第二个窗口中根据上述值本身禁用多个文本框。

所述文本框的特征还在于验证绑定。现在我的验证任务完美无缺,但我无法绑定到IsEnabled TextBox 属性。

这是我的 XAML 的 sn-p,其中包含一个 TextBox(目前是我绑定的唯一一个):

<TextBox x:Name="tbSlave1" Validation.Error="ValidationError" IsEnabled="{Binding TextBoxEnabled}" Text="{Binding UpdateSourceTrigger=PropertyChanged, Path=SlavePoint1Name, ValidatesOnDataErrors=true, NotifyOnValidationError=true}"/>

虽然这是我的第二个窗口类:

public partial class GeneratorWindow : Window, INotifyPropertyChanged
{
    private readonly Validator validator = new Validator();

    private int noOfErrorsOnScreen;

    public GeneratorWindow()
    {
        this.InitializeComponent();
        this.grid.DataContext = this.validator;
    }

    public int NumberOfPoints { private get; set; }

    public int MainPDC { private get; set; }

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

    private Boolean IsEnabled;
    public Boolean TextBoxEnabled
    {
        get { return IsEnabled; }

        set
        {
            IsEnabled = value;
            NotifyPropertyChanged("TextBoxEnabled");
        }
    }

    private void ValidationError(object sender, ValidationErrorEventArgs eventArgs)
    {
        if (eventArgs.Action == ValidationErrorEventAction.Added)
        {
            this.noOfErrorsOnScreen++;
        }
        else
        {
            this.noOfErrorsOnScreen--;
        }
    }

    private void ValidationCanBeExecuted(object sender, CanExecuteRoutedEventArgs eventArgs)
    {
        eventArgs.CanExecute = this.noOfErrorsOnScreen == 0;
        eventArgs.Handled = true;
    }

    private void ValidationExecuted(object sender, ExecutedRoutedEventArgs eventArgs)
    {
        // If the validation was successful, let's generate the files.
        this.Close();

        eventArgs.Handled = true;
    }
}

现在,我得到的是我的窗口被禁用(无法选择任何文本框),显然,这是:

System.Windows.Data 错误:40:BindingExpression 路径错误:在“对象”“验证器”(HashCode=14499481)上找不到“TextBoxEnabled”属性。 BindingExpression:Path=TextBoxEnabled; DataItem='验证器' (HashCode=14499481);目标元素是'TextBox'(名称='tbSlave1');目标属性是“IsEnabled”(类型“布尔”)

据我所知,罪魁祸首是我在类构造函数中管理DataContext 的方式。我可能需要在验证器行中添加一些内容或完全更改它,但我不明白如何。

【问题讨论】:

  • {Binding TextBoxEnabled} 使用当前 DataContext 作为其源对象,该对象显然没有 TextBoxEnabled 属性(错误消息中明确说明了这一点)。您需要将窗口指定为源对象,例如通过设置 Binding 的 ElementName 或 RelativeSource。
  • 请出示您的 Validator 课程(请参阅 TextBoxEnabled 缺失)
  • @Clemens,我应该使用类似于{Binding Path=TextBoxEnabled, RelativeSource={RelativeSource Self}}RelativeSource 吗?
  • 不是Self,而是AncestorType=Window
  • 好的,它确实有效。谢谢。

标签: c# wpf binding


【解决方案1】:

如果您将DataContext 设置为GeneratorWindow 并相应地更新您的绑定,我认为您应该没问题。为此,您需要将 Validator 更改为公共属性。

更改的验证器定义:

public Validator Validator { get; } = new Validator();

数据上下文:

this.grid.DataContext = this;

更新绑定:

<TextBox x:Name="tbSlave1" 
         Validation.Error="ValidationError" 
         IsEnabled="{Binding TextBoxEnabled}" 
         Text="{Binding UpdateSourceTrigger=PropertyChanged, 
                        Path=Validator.SlavePoint1Name, 
                        ValidatesOnDataErrors=true, 
                        NotifyOnValidationError=true}"/>

【讨论】:

  • Path=validator.SlavePoint1Name 将不起作用,因为validator 不是公共属性。
  • @Davide3i 它在哪些方面不适合您?您收到错误消息吗?也请给我们看Validator的代码。
  • 它没有访问所有验证器绑定的权限。在任何情况下,@Clemens 提出的方法都可以正常工作,而无需对我现有的代码进行任何更改。
猜你喜欢
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 2011-05-18
  • 2015-06-05
  • 1970-01-01
  • 1970-01-01
  • 2011-03-04
  • 1970-01-01
相关资源
最近更新 更多