c# - 为什么我对 TextBox 验证规则参数的绑定不起作用?
问题描述
我有一个带有需要验证的 TextBox 的用户控件。验证将根据 UC 中依赖属性的值而有所不同,因此我需要将其作为参数传递。要传递参数,我使用将数据绑定值传递给验证规则作为指导。但是,我使用的绑定不起作用,我不知道为什么。我已经拼了命,用谷歌搜索了我能想到的一切,没有快乐。
这是代码。希望我已经提供了足够的...
在用户控件中,我有这个 XAML。
<TextBox Name="ValueBox"
PreviewMouseLeftButtonUp="OnPreviewMouseLeftButtonUp"
Height="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=Height}"
BorderThickness="0"
TextAlignment="Center"
VerticalContentAlignment="Center">
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=IsControlEnabled}"
Value="False">
<Setter Property="Background" Value="{StaticResource DisabledColor}"/>
</DataTrigger>
<DataTrigger
Binding="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=InteractionMode}"
Value="{x:Static local:TreatmentScheduleNumberBoxUserControl+InteractionModes.Select}">
<Setter Property="IsReadOnly" Value="True" />
<Setter Property="Cursor" Value="{x:Static Cursors.Hand}" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
<TextBox.Resources>
<local:NumberBoxValueConverter x:Key="NumberBoxConverter"/>
</TextBox.Resources>
<TextBox.Text>
<tools:ConverterBindableParameter
Converter="{StaticResource NumberBoxConverter}"
ConverterParameterBinding="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=TreatmentLampType}">
<!--https://social.technet.microsoft.com/wiki/contents/articles/31422.wpf-passing-a-data-bound-value-to-a-validation-rule.aspx-->
<tools:ConverterBindableParameter.Binding>
<Binding RelativeSource="{RelativeSource AncestorType=UserControl}" Path="Value" FallbackValue="3">
<Binding.ValidationRules>
<local:NumberBoxValidationRule>
<local:NumberBoxValidationRule.Wrapper>
<local:Wrapper NumberBoxUsage1="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=NumberBoxUsage
, Converter={StaticResource DebugDummyConverter, PresentationTraceSources.TraceLevel=High}}" />
</local:NumberBoxValidationRule.Wrapper>
</local:NumberBoxValidationRule>
</Binding.ValidationRules>
</Binding>
</tools:ConverterBindableParameter.Binding>
</tools:ConverterBindableParameter>
</TextBox.Text>
</TextBox>
问题在于这个绑定,其中NumberBoxUsage1
是验证环境NumberBoxUsage
中的依赖属性,而在 UC 中是依赖属性。
<local:Wrapper NumberBoxUsage1="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=NumberBoxUsage
, Converter={StaticResource DebugDummyConverter, PresentationTraceSources.TraceLevel=High}}" />
当它运行时,NumberBoxUsage1
仍然是默认值,并且没有分配NumberBoxUsage
. 我可以将绑定更改为文字赋值,这很有效。如图所示,我添加了一个虚拟转换器,PresentationTraceSources
但从未调用过该转换器,并且“输出”窗口中没有任何痕迹。任何帮助表示赞赏。
我可能会补充一点,这一切都TextBox
很好。这是相关的 C# 内容。
包装器
public class Wrapper : DependencyObject
{
public NumberBoxUsages NumberBoxUsage1 {
get => (NumberBoxUsages)GetValue(NumberBoxUsage1Property);
set => SetValue(NumberBoxUsage1Property, value);
}
public static readonly DependencyProperty NumberBoxUsage1Property =
DependencyProperty.Register(nameof(NumberBoxUsage1), typeof(NumberBoxUsages), typeof(Wrapper),
new FrameworkPropertyMetadata(
NumberBoxUsages.UvPrim,
(sender, e) =>
{
var dObj = sender as Wrapper;
var x = dObj.NumberBoxUsage1;
// leave for debugging help
}
));
}
NumberBoxValidationRule
public class NumberBoxValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
if (value == null)
{
return new ValidationResult(false, "Please enter a value");
}
if (Wrapper.NumberBoxUsage1 == NumberBoxUsages.UvbPriPct)
{
}
return ValidationResult.ValidResult;
}
public Wrapper Wrapper { get; set; }
}
ConverterBindableParameter
public class ConverterBindableParameter : MarkupExtension
{
#region Public Properties
public Binding Binding { get; set; }
public IValueConverter Converter { get; set; }
public Binding ConverterParameterBinding { get; set; }
#endregion
#region Overridden Methods
public override object ProvideValue(IServiceProvider serviceProvider)
{
var multiBinding = new MultiBinding();
multiBinding.Bindings.Add(Binding);
multiBinding.Bindings.Add(ConverterParameterBinding);
var adapter = new MultiValueConverterAdapter
{
Converter = Converter
};
multiBinding.Converter = adapter;
return multiBinding.ProvideValue(serviceProvider);
}
[ContentProperty("Converter")]
public class MultiValueConverterAdapter : IMultiValueConverter
{
public IValueConverter Converter { get; set; }
private object lastParameter;
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (Converter == null) return values[0]; // Required for VS design-time
if (values.Length > 1) lastParameter = values[1];
return Converter.Convert(values[0], targetType, lastParameter, culture);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
if (Converter == null) return new object[] { value }; // Required for VS design-time
return new object[] { Converter.ConvertBack(value, targetTypes[0], lastParameter, culture) };
}
}
#endregion
}
解决方案
你错过了BindingProxy
捕获的DataContext
:
public class BindingProxy : System.Windows.Freezable
{
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new PropertyMetadata(null));
}
XAML:
<TextBox.Resources>
<local:NumberBoxValueConverter x:Key="NumberBoxConverter"/>
<local:BindingProxy x:Key="proxy" Data="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}"/>
</TextBox.Resources>
...
<local:Wrapper NumberBoxUsage1="{Binding Source={StaticResource proxy}, Path=Data.NumberBoxUsage,
Converter={StaticResource DebugDummyConverter}}" />
推荐阅读
- python-3.x - 用另一个变量循环一个变量范围
- php - 使用 .htaccess 捕获域名
- r - 如何使用for循环将注释添加到ggplot的顶部
- javascript - axios 在 postman 上运行时返回 404 错误
- c - C 使用 ncurses 库使用 getch() 屏蔽密码
- google-apps-script - 记录由谷歌表格制作的任何副本
- batch-file - 如何根据使用 WinSCP 上传的结果将文件批量移动到不同的文件夹
- reactjs - GatsbyJS + Netlify + MDX 加载器问题
- python - Pyexcel,如何使用 pyexcel 将 dict 保存到 csv 文件?
- php - PHP MySQL新手,实时服务器上的身份验证问题