我正在FooBox(升级的文本框)中动态使用ValidationRule。 直接在Window中使用时效果很好。
我还有另一个自定义控件(LatLonEditor),可以使用FooBox管理纬度和经度。 在这种特殊情况下,当我获得FooBox值的绑定时,我总是会获得第一个LatLonEditor的第一个FooBox的绑定。
我已经花了整整一天时间尝试解决此问题,而我的解决方案也用光了。 我已经阅读了BindingOperations.GetBinding源代码(没有给我一个提示)。 我创建了一个隔离的项目来重现该问题,剥离了代码的所有无用部分。
FooBox模板
<ControlTemplate x:Key="FooBoxTemplate" TargetType="{x:Type local:FooBox}">
<TextBox x:Name="Editor" Text="{Binding Path=Value, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="0,0,1,0" />
<ControlTemplate.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors).CurrentItem.ErrorContent}"/>
<Setter Property="BorderBrush" TargetName="Editor" Value="Red" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="DefaultFooBoxStyle" TargetType="{x:Type local:FooBox}">
<Setter Property="Template" Value="{StaticResource FooBoxTemplate}"/>
<Setter Property="Height" Value="24" />
<Setter Property="Validation.ErrorTemplate" Value="{x:Null}" />
<Setter Property="Focusable" Value="False" />
</Style>
<Style TargetType="{x:Type local:FooBox}" BasedOn="{StaticResource DefaultFooBoxStyle}" />
FooBox控件
public class FooBox : Control
{
static FooBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(FooBox), new FrameworkPropertyMetadata(typeof(FooBox)));
}
public enum Type
{
Int,
Float,
Double,
String
}
private bool _templateApplied = false;
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_templateApplied = true;
LoadValidationRules();
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(string), typeof(FooBox), new FrameworkPropertyMetadata()
{
BindsTwoWayByDefault = true,
DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
});
public string Value
{
get { return (string)GetValue(ValueProperty); }
set
{
SetValue(ValueProperty, value);
}
}
public static readonly DependencyProperty ValueTypeProperty =
DependencyProperty.Register("ValueType", typeof(Type), typeof(FooBox), new FrameworkPropertyMetadata()
{
DefaultValue = Type.String
});
public Type ValueType
{
get { return (Type)GetValue(ValueTypeProperty); }
set
{
SetValue(ValueTypeProperty, value);
}
}
/// <summary>
/// For integral types, this is the max acceptable value
/// </summary>
public static readonly DependencyProperty DomainMaxProperty =
DependencyProperty.Register("DomainMax", typeof(decimal?), typeof(FooBox), new FrameworkPropertyMetadata());
public decimal? DomainMax
{
get { return (decimal?)GetValue(DomainMaxProperty); }
set
{
SetValue(DomainMaxProperty, value);
}
}
private void LoadValidationRules()
{
if (_templateApplied)
{
//For the second LatLonEditor, i've got the binding of the previous one
Binding b = BindingOperations.GetBinding(this, ValueProperty);
if (b != null)
{
b.ValidationRules.Clear();
if (ValueType == Type.Double)
{
b.ValidationRules.Add(new DoubleValidationRule()
{
DomainMax = DomainMax
});
}
}
}
}
}
LatLonEditor模板
<ControlTemplate x:Key="LatLonDecimalDegreesEditorTemplate" TargetType="{x:Type local:LatLonEditor}">
<local:FooBox x:Name="PART_DD" ValueType="Double" Margin="2,0"
Value="{Binding Value, Delay=500, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,
RelativeSource={RelativeSource TemplatedParent}}"/>
<ControlTemplate.Triggers>
<Trigger Property="Type" Value="Latitude">
<Setter TargetName="PART_DD" Property="DomainMax" Value="90" />
</Trigger>
<Trigger Property="Type" Value="Longitude">
<Setter TargetName="PART_DD" Property="DomainMax" Value="180" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="DefaultLatLonEditorStyle" TargetType="{x:Type local:LatLonEditor}">
<Setter Property="Template" Value="{StaticResource LatLonDecimalDegreesEditorTemplate}"/>
</Style>
<Style BasedOn="{StaticResource DefaultLatLonEditorStyle}" TargetType="{x:Type local:LatLonEditor}" />
LatLonEditor控件
public class LatLonEditor : Control
{
#region Statements
#endregion
#region Constructor/Destructor
static LatLonEditor()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(LatLonEditor), new FrameworkPropertyMetadata(typeof(LatLonEditor)));
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
}
#endregion
/// <summary>
/// The types of value that can be input
/// </summary>
public enum CoordinateValueType : byte
{
Latitude,
Longitude
}
#region Properties
/// <summary>
/// Get/Set the input mode for this instance
/// </summary>
public static readonly DependencyProperty TypeProperty =
DependencyProperty.Register("Type", typeof(CoordinateValueType), typeof(LatLonEditor), new FrameworkPropertyMetadata()
{
DefaultValue = CoordinateValueType.Latitude
});
public CoordinateValueType Type
{
get { return (CoordinateValueType)GetValue(TypeProperty); }
set { SetValue(TypeProperty, value); }
}
/// <summary>
/// Formatted value to use externally
/// </summary>
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(double?), typeof(LatLonEditor), new FrameworkPropertyMetadata());
public double? Value
{
get
{
return (double?)GetValue(ValueProperty);
}
set
{
SetValue(ValueProperty, value);
}
}
#endregion
}
用法
<controls:LatLonEditor x:Name="H3LP" Width="120" Type="Longitude" Value="3" />
<controls:LatLonEditor x:Name="IfYouPlease" Width="120" Type="Latitude" Value="5" />
第一个LatLonEditor的最大值应为180 第二个LatLonEditor的最大值应为90
DomainMax已由触发器正确设置。
实际结果是两个控件的最大值均为90 (第一次绑定将应用第二个控件的规则)
我当然想念什么,但是我看不到什么? :-(
答案 0 :(得分:1)
您应该首先获得对您对其应用绑定的元素的引用,然后使用$today = date("D");
switch($today){
case "Mon":
case "Tue":
case "Wed":
$days = (mktime(16, 0, 0) <= time())? 2 : 1;
break;
case "Thu":
$days = (mktime(16, 0, 0) <= time())? 4 : 1;
break;
case "Fri":
$days = (mktime(16, 0, 0) <= time())? 5 : 4;
break;
case "Sat":
$days = 4;
break;
case "Sun":
$days = 3;;
break;
default:
break;
}
if ( isset($days) ) {
echo "<p>For Delivery on <strong> " . date('D jS', strtotime($Date. " + {$days} days")). "</strong><p>";
}
else {
echo "No information available for that day.";
}
:
BindingOperations.GetBinding
由于不应该修改private void LoadValidationRules()
{
if (_templateApplied)
{
TextBox Editor = Template.FindName("Editor", this) as TextBox;
Binding b = BindingOperations.GetBinding(Editor, TextBox.TextProperty);
if (b != null)
{
...
}
}
}
,因此您还可以通过编程方式创建初始绑定:
Binding
然后,您当然将为每个实例获得唯一的绑定。