在Windows Presentation Foundation(WPF)中,附加属性是依赖属性的一种特殊形式,它没有传统的属性“包装器”。
是否可以在不知道绑定属性的情况下直接设置双向绑定后面的值? 我有一个附加属性,它绑定到这样的属性: 是否可以在不知道绑定属性的情况下直接设置双向绑定后面的值? 我有一个附加属性,它绑定到这样的属性: <Element my:Utils.MyProperty="{Binding Something}" /> 现在我想从附加属性的角度更改有效存储在 Something 中的值。所以我无法直接访问绑定属性,而只能引用 DependencyObject (即 Element 实例)和 DependencyProperty 对象本身。 简单地通过DependencyObject.SetValue设置它时的问题是,这有效地删除了绑定,但我想更改底层绑定属性。 使用 BindingOperations 我可以获得 Binding 和 BindingExpression。现在有没有办法访问它背后的属性并改变它的值? 好吧,我现在已经自己在绑定表达式上使用一些反射技巧解决了这个问题。 我基本上查看绑定路径和响应数据项,并尝试自己解决绑定。对于更复杂的绑定路径,这可能会失败,但对于如上面示例中的简单属性名称,这应该可以正常工作。 BindingExpression bindingExpression = BindingOperations.GetBindingExpression(dependencyObj, dependencyProperty); if (bindingExpression != null) { PropertyInfo property = bindingExpression.DataItem.GetType().GetProperty(bindingExpression.ParentBinding.Path.Path); if (property != null) property.SetValue(bindingExpression.DataItem, newValue, null); } 尝试在 PropertyMetadata 中设置默认值 您可以在 MSDN 上找到更多信息 - http://msdn.microsoft.com/en-us/library/system.windows.propertymetadata.aspx 这是一个例子: public Boolean State { get { return (Boolean)this.GetValue(StateProperty); } set { this.SetValue(StateProperty, value); } } public static readonly DependencyProperty StateProperty = DependencyProperty.Register( "State", typeof(Boolean), typeof(MyStateControl),new PropertyMetadata(myDefaultValue)); 简单地通过 DependencyObject.SetValue 设置它时的问题是 这有效地消除了绑定,但我想改变 底层绑定属性。 如果 Binding.Mode 设置为 OneWay,则为 true。如果将其设置为 TwoWay,则使用 DependencyObject.SetValue 将不会删除其绑定。 这是来自 Pro WPF 4.5 in C# 的引用(第 232 页): 删除绑定:如果您想删除绑定,以便可以 按照通常的方式设置属性,你需要帮助 ClearBinding() 或 ClearAllBindings() 方法。仅仅这样是不够的 对属性应用新值。如果您使用双向绑定, 您设置的值将传播到链接的对象,并且两者 属性保持同步。 因此,能够使用 SetValue 更改(和传播) my:Utils.MyProperty 而不删除其绑定: <Element my:Utils.MyProperty="{Binding Something, Mode=TwoWay}" /> 您可以通过虚拟对象上的绑定来传递值。 public static void SetValue(BindingExpression exp, object value) { if (exp == null) throw new ValueCannotBeNullException(() => exp); Binding dummyBinding = new Binding(exp.ParentBinding.Path.Path); dummyBinding.Mode = BindingMode.OneWayToSource; dummyBinding.Source = exp.DataItem; SetValue(dummyBinding, value); } public static void SetValue(Binding binding, object value) { BindingDummyObject o = new BindingDummyObject(); BindingOperations.SetBinding(o, BindingDummyObject.ValueProperty, binding); o.Value = value; BindingOperations.ClearBinding(o, BindingDummyObject.ValueProperty); } 这是我的虚拟对象 internal class BindingDummyObject : DependencyObject { public object Value { get { return (object)GetValue(ValueProperty); } set { SetValue(ValueProperty, value); } } public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(object), typeof(BindingDummyObject)); } 在尝试实现由枚举支持的菜单时,我遇到了类似的问题。我希望能够将底层属性(这是一个枚举)设置为与菜单项关联的值。 在我的示例中,我将两个属性附加到 MenuItem: public static readonly DependencyProperty EnumTargetProperty = DependencyProperty.RegisterAttached( "EnumTarget", typeof(object), typeof(MenuItem), new PropertyMetadata(null, EnumTargetChangedCallback) ); public static readonly DependencyProperty EnumValueProperty = DependencyProperty.RegisterAttached( "EnumValue", typeof(object), typeof(MenuItem), new PropertyMetadata(null, EnumValueChangedCallback) ); 标记看起来像这样: <MenuItem.ItemContainerStyle> <Style TargetType="MenuItem"> <Setter Property="IsCheckable" Value="True"/> <Setter Property="local:EnumMenuItem.EnumValue" Value="{Binding EnumMember}"/> <Setter Property="local:EnumMenuItem.EnumTarget" Value="{Binding RelativeSource={RelativeSource AncestorType=local:MainWindow}, Path=DataContext.Settings.AutoUpdateModel.Ring}"/> <Setter Property="Header" Value="{Binding DisplayName}"/> <Setter Property="ToolTip" Value="{Binding ToolTip}"/> </Style> </MenuItem.ItemContainerStyle> 父菜单项的项目源绑定到 MarkupExtension 实现,该实现为枚举中的每个成员提供值。 现在,当选中菜单项时,我使用此代码来设置属性的值,而无需删除绑定。 menuItem.Checked += (sender, args) => { var checkedMenuItem = (MenuItem)sender; var targetEnum = checkedMenuItem.GetValue(EnumTargetProperty); var menuItemValue = checkedMenuItem.GetValue(EnumValueProperty); if (targetEnum != null && menuItemValue != null) { var bindingExpression = BindingOperations.GetBindingExpression(d, EnumTargetProperty); if (bindingExpression != null) { var enumTargetObject = bindingExpression.ResolvedSource; if (enumTargetObject != null) { var propertyName = bindingExpression.ResolvedSourcePropertyName; if (!string.IsNullOrEmpty(propertyName)) { var propInfo = enumTargetObject.GetType().GetProperty(propertyName); if (propInfo != null) { propInfo.SetValue(enumTargetObject, menuItemValue); } } } } } }; 这似乎适合我的具有复杂路径的场景。 希望这对您有所帮助! 这是我为TextBlock所做的事情: BindingExpression bindingExpression = textBlock.GetBindingExpression(TextBlock.TextProperty); string propertyName = bindingExpression.ResolvedSourcePropertyName; PropertyInfo propertyInfo; Type type = bindingExpression.DataItem.GetType(); object[] indices = null; if (propertyName.StartsWith("[") && propertyName.EndsWith("]")) { // Indexed property propertyInfo = type.GetProperty("Item"); indices = new object[] { propertyName.Trim('[', ']') }; } else propertyInfo = type.GetProperty(propertyName); if (propertyInfo.PropertyType == typeof(string)) { propertyInfo.SetValue(bindingExpression.DataItem, text, indices); // To update the UI. bindingExpression.UpdateTarget(); } 只需使用 SetCurrentValue 方法即可(https://learn.microsoft.com/en-us/dotnet/api/system.windows.dependencyobject.setcurrentvalue): SetCurrentValue 方法更改属性的有效值,但现有的触发器、数据绑定和样式将继续工作
Maui-Net.8-集合视图中的所有项目都有动画。不是被窃听的那个
我的毛伊岛 Android 项目之一我在页面中有一个集合视图。 我像这样设置集合视图的属性: 我的毛伊岛 Android 项目之一,我在页面中有一个集合视图。 我像这样设置集合视图的属性: <CollectionView x:Name="ModelList" SelectionMode="None" IsGrouped="False" ItemSizingStrategy="MeasureAllItems" ItemsSource="{Binding Models}" VerticalOptions="FillAndExpand"> <CollectionView.ItemsLayout> <GridItemsLayout Span="2" Orientation="Vertical"/> </CollectionView.ItemsLayout> <CollectionView.ItemTemplate> <DataTemplate x:DataType="models:Model"> <VerticalStackLayout Spacing="3" HorizontalOptions="Center" Margin="0,0,0,10"> <views:CustomView x:Name="Cstm" IsBusy="{Binding IsBusy, Source={RelativeSource AncestorType={x:Type viewmodel:ViewModel}}}" <-- IsBusy property is bindable Property.--> ControlTemplate="{StaticResource TappedView}"> <views:CustomView.GestureRecognizers> <TapGestureRecognizer Command="{Binding ModelDetailsPageCommand, Source={RelativeSource AncestorType={x:Type viewmodel:ProjectPageViewModel}}}" CommandParameter="{Binding Id}"/> </views:CustomView.GestureRecognizers> </views:CustomView> </VerticalStackLayout> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView> 集合视图的项目模板使用自定义视图填充,并且该自定义视图的控件模板是自定义控件。它的布局是这样的: <ControlTemplate x:Key="CustomControl"> <Border x:Name="CustomLayout"> <Grid> <Border attached:ControlTappedAttachedProperty.Value="{TemplateBinding IsBusy}"> <--AttachedProperty--> <Image HeightRequest="60"> <Image.Source> <FontImageSource FontFamily="Font" Glyph="{x:Static Font.ThereIsAProblem}" Color="{StaticResource YsSomeColor}" /> </Image.Source> </Image> </Border> </Grid> </Border> </ControlTemplate> 此控件附加属性的值绑定自定义控件的可绑定属性。 附加属性只是对附加的视觉元素进行动画处理。 问题就在这里。当点击集合视图中的项目时,所有项目都会有动画。不只是被窃听的那个。 尝试过: 将选择模式更改为单选不起作用。 附加附加属性顶部父对象(Collectionview item -> <views:CustomView/>)而不是自定义控件无效。同样的问题。 所以...我很困惑。任何帮助任何想法都将非常感激。预先感谢。 在您的代码中,您使用以下绑定: IsBusy="{Binding IsBusy, Source={RelativeSource AncestorType={x:Type viewmodel:ViewModel}}}" 此 BindableProperty 绑定到您的 IsBusy 中的 ViewModel 属性。因此,当您点击某个项目并更改 IsBusy 值时,所有项目都会反映此更改,因为它们共享相同的 ViewModel-level IsBusy 属性。 为了确保每个项目都可以有自己的 IsBusy 状态,请考虑向模型类添加 IsBusy 属性。然后,在点击事件中,您可以更新特定项目的 IsBusy 属性,如下所示: model.IsBusy = true; 这样,列表中每个项目的 IsBusy 状态都是唯一的。
假设我有控件 A,它附加了属性 AP。控件 B 将其用作 A.AP="value"。 附加属性更改事件签名与依赖属性相同,只是...
假设我有控件 A,它附加了属性 AP。控件 B 将其用作 A.AP="value"。 附加属性更改事件签名与依赖属性相同,只是 d ...
将 Collection 类型的 AttachedProperty 绑定到 TemplatedParent
我想创建一个附加属性来保存 MenuItem 对象的集合。这些将在我的 GroupBox 自定义 ControlTemplate 中使用。在该 ControlTemplate 中,我想使用我的自定义
我必须创建一个 Binding 来读取对象属性的值,该对象的属性值是附加属性的值。 在 XAML 中我可以这样: 我必须创建一个 Binding 来读取对象的属性值,该属性值是附加属性的值。 在 XAML 中我可以这样: <TextBlock Text="{Binding Path=(myns:MyDependencyObject.MyAttachedProperty).NestedProperty, Mode=OneWay}"/> 如何在 C# 代码中做到这一点? 您可以通过以下方法做到这一点: var path = new PropertyPath("(0).NestedProperty", MyDependencyObject.MyAttachedProperty); var binding = new Binding() { Path = path, Mode = BindingMode.OneWay }; myTextBlock.SetBinding(TextBlock.TextProperty, binding); PropertyPath 使用的构造函数如下: public PropertyPath(string path, params object[] pathParameters) 请注意 "(0)" 与 string.Format 语法类似,其中 (0) 对应于 pathParameters 参数列表中的第一个参数。 微软文档对此不太清楚。
我什么时候应该使用 FrameworkPropertyMetadata 或 UIPropertyMetadata 而不是普通的 PropertyMetadata?
在查看示例附加属性和行为时,我发现 FrameworkPropertyMetadata、UIPropertyMetadata 和 PropertyMetadata 的使用混杂在一起。因为他们都形成了继承阶层...
我尝试使用带有附加属性的绑定。但无法让它发挥作用。 公开课附 { 公共静态依赖属性测试属性= DependencyProperty.RegisterAttached("
在同一 SSRS 电子邮件中发送 Excel 附件和正文中的图像
我正在尝试使用 SSRS 发送报告,其中在电子邮件正文中包含图像,并且附有 Excel 报告。 我想将图像放在蓝色框中(电子邮件正文),然后生成报告...
我正在将一个CustomControl(让我们称它为MyButton)的高度绑定到CustomControl样式内的一个可继承的附加属性。
如何克服ItemsPanelTemplate中的Grid.Row / Column的错误?
创建了一个简单的AP属性,以简化与元素模板的绑定。代替此:
除了属性(附加)外,我还想添加一个类(searchAnchor)。能够使用属性和类的正确拼写是什么? ....附加:{...
我正在尝试了解通知如何在WPF中用于附加属性。例如,考虑ScrollViewer.CanContentScrollProperty属性。假设我们有以下列表框
我正在尝试了解通知如何在WPF中用于附加属性。例如,考虑ScrollViewer.CanContentScrollProperty属性。假设我们有以下列表框
我在XAML中有一个矩形,并且想要在后面的代码中更改其Canvas.Left属性:
[你好,在阅读了很多小时的可见性绑定主题之后,我在这里问,因为我无法使案例发挥作用。我有一个带有自定义附加属性的网格(类型为System ....
我正在尝试将嵌套在附加属性内部的元素绑定到我的DataContext,但是问题是附加属性不是逻辑树的一部分,因此不能正确使用...
如何将具有Command的ContextMenu绑定到附加属性?
我有一个名为DockSite的外部控件。从DockSite控件显示ContextMenu时,将调用MenuOpening事件处理程序。我想将ContextMenu添加到默认的ContextMenu ...
我出于学习目的创建了附加属性,但无法获得成功的结果。公共类AQDatagridDependencyProperties:DependencyObject {public static void SetCustomDataSource(...
我们有一个WPF应用程序,该应用程序的查询计数结果显示在屏幕上。我们最初将结果定义为按钮,以便在单击结果时,应用程序将显示详细的...