有一个非常奇怪的问题令我感到困惑.就像下面的代码一样,我创建了一个[Button]并将其[Canvas.LeftProperty]多重绑定到[Entity.X]和[Entity.Z].[实体] ]类已实现[INotifyPropertyChaned].
它在Convert()方法中运行良好,[Entity.X]和[Entity.Z]正确传递给[Canvas.LeftProperty].
但问题是:当我用Canvas.SetLeft()方法更改[Button]的位置时,转换了ConvertBack()方法,但是没有将正确的值传递给[Entity],[in]中的[value] Entity.X]的设置部分似乎始终是旧部分.
PS:我发现了一个类似的问题,但它也没有解决.. :(
类似的问题:http://social.msdn.microsoft.com/Forums/zh-CN/wpf/thread/88B1134B-1DAA-4A54-94ED-BD724724D1EF
<Canvas>
<Button x:Name="btnTest">
<Canvas>
Run Code Online (Sandbox Code Playgroud)
private void Binding()
{
var enity=DataContext as Entity;
var multiBinding=new MutiBinding();
multiBinding.Mode=BindingMode.TwoWay;
multiBinding.Converter=new LocationConverter();
multiBinding.Bindings.Add(new Binding("X"));
multiBinding.Bindings.Add(new Binding("Z"));
btnTest.SetBinding(Canvas.LeftProperty,multiBinding);
}
Run Code Online (Sandbox Code Playgroud)
public class LocationConverter: IMultiValueConverter
{
public object Convert(object[] values, TypetargetType,object parameter, CultureInfo culture)
{
return (double)values[0]*(double)values[1];
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
return new object[]{ (double)value,Binding.DoNoting};//!!value here is correct
}
}
Run Code Online (Sandbox Code Playgroud)
public class Entity:INotifyPropertyChanged
{ …Run Code Online (Sandbox Code Playgroud) 我们知道,Attached Property在wpf中广泛扩展了属性系统.但是我们熟悉的所有示例几乎都是父对象的,例如DockPanel.Dock/Grid.Row等.但是在MSDN中查看文档之后,我发现其他一些附属物的用法:
从MSDN:附加属性概述/如何使用附加属性由拥有类型
1.定义附加属性的类型被设计为使得它可以是将为附加属性设置值的元素的父元素.然后,类型通过内部逻辑对某些对象树结构迭代其子对象,获取值,并以某种方式对这些值进行操作.(母公司定义)
2.定义附加属性的类型将用作各种可能的父元素和内容模型的子元素.(儿童定义)
3.定义附加属性的类型表示服务.其他类型设置附加属性的值.然后,当在服务的上下文中评估设置属性的元素时,通过服务类的内部逻辑获得附加属性值.(用作公共服务)
由于附加属性可以由用户定义,我认为也许我们可以使用"CallBackMethod"来处理它.所以我编写了一些试验以验证我的想法(第4.部分代码):
1.自定义一个子控件("Son"),它定义了一个名为"CellBorderThicknessProperty"的附加属性,并使用"PropertyChangedCallBack"来更新布局;
2.创建一个父控件("父"),其模板包含子控件.
3.在Window中使用父控件并设置child.CellBorderThickness的值;
1.如你所见,在"儿童类型"中暴露"父类型"并不是一个好方法,特别是我们不会有多少父母会...
2.本试验没有奏效,'当"PropertyChangedCallBack"被解雇时,父亲的模板尚未应用!所以,Father.SetBorderThickness()将什么都不做!
我非常渴望了解MS开发人员如何处理Child-Defined问题.
例如:WPFToolkit中的ScrollViwer.VerticalScrollBarVisibility:DataGrid?
<Style TargetType={x:Type Son}>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border BorderThickness={TemplateBinding CellBorderThickness}>
...
</Border>
</ControlTemplate>
<Setter.Value>
</Setter>
Run Code Online (Sandbox Code Playgroud)
public class Son: Control
{
public static readonly DependencyProperty CellBorderThicknessProperty = DependencyProperty.RegisterAttached("CellBorderThickness", typeof(Thickness), typeof(Son), new FrameworkPropertyMetadata(new Thickness(0.2), FrameworkPropertyMetadataOptions.AffectsRender, CellBorderThicknessProperty_ChangedCallBack));
public static void SetCellBorderThickness(UIElement obj, Thickness value)
{
obj.SetValue(Son.CellBorderThicknessProperty, value);
}
public static Thickness …Run Code Online (Sandbox Code Playgroud) 当我尝试在WPF/.NET 3.5中开发自定义控件时出现严重问题.
1.当我在同一个窗口中添加两个实例时,看起来第二个将始终具有第一个依赖属性值,即使test2只是在不应用模板的情况下构造(例如:tes2.TopItems/CenterItems/BottomItems是相同的使用tes1包括Count,Items ...).
2.当我删除其中任何一个时,它会好的.
3. TopItems/CenterItems/BottomItems在OnApplyTemplate()中初始化.
4.更改属性"Calendar"和"CalendarViewType"将调用PropertyChangedCallBack().
5."TopItems","CenterItems","BttomItems"在Control的模板中的{TemplateBinding}中使用.
6.我尝试使用"Normal Property""{Binding RelativeSource = TemplatedParent}"而不是"Depdendency Property"和{TemplateBinding},它运作良好!!!!多奇怪!!!
<Window>
<Grid>
<common:CalendarTitle x:Name="test1" Calendar="{Binding Calendar}" CalendarViewType="Month_Week"></common:CalendarTitle>
<common:CalendarTitle x:Name="test2" Calendar="{Binding Calendar}"></common:CalendarTitle>
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
public static readonly DependencyProperty CalendarProperty = DependencyProperty.Register("Calendar", typeof(ICalendar), typeof(CalendarTitle), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender, PropertyChangedCallback));
public static readonly DependencyProperty CalendarViewTypeProperty = DependencyProperty.Register("CalendarViewType", typeof(CalendarViewType), typeof(CalendarTitle), new FrameworkPropertyMetadata(CalendarViewType.Week_Day, FrameworkPropertyMetadataOptions.AffectsRender, PropertyChangedCallback));
public static readonly DependencyProperty TopItemsProperty = DependencyProperty.Register("TopItems", typeof(IEnumerable<ICalendarItem>), typeof(CalendarTitle), new FrameworkPropertyMetadata(new ObservableCollection<ICalendarItem>()));
public static readonly DependencyProperty CenterItemsProperty = DependencyProperty.Register("CenterItems", typeof(IEnumerable<ICalendarItem>), typeof(CalendarTitle), new …Run Code Online (Sandbox Code Playgroud)