- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
NOTE: Before reading the subject and instantly marking this as a duplicate, please read the entire question to understand what we are after. The other questions which describe getting the
BindingExpression
, then callingUpdateTarget()
method does not work in our use-case. Thanks!
INotifyPropertyChanged
,即使关联的属性没有发生变化,我也可以简单地通过引发带有该属性名称的
PropertyChanged
事件来重新评估绑定(bind)。如果该属性是
DependencyProperty
而我无权访问目标,而只能访问源,我该怎么做?
ItemsControl
的自定义
MembershipList
,它公开了一个类型为
Members
的名为
ObservableCollection<object>
的属性。这是与
Items
或
ItemsSource
属性分开的属性,这些属性的行为与任何其他
ItemsControl
相同。这样定义...
public static readonly DependencyProperty MembersProperty = DependencyProperty.Register(
"Members",
typeof(ObservableCollection<object>),
typeof(MembershipList),
new PropertyMetadata(null));
public ObservableCollection<object> Members
{
get { return (ObservableCollection<object>)GetValue(MembersProperty); }
set { SetValue(MembersProperty, value); }
}
Items
/
ItemsSource
中的所有成员设置样式,这些成员在
Members
中的显示方式也与未显示的成员不同。换句话说,我们试图突出显示两个列表的交集。
Members
可能包含根本不在
Items
/
ItemsSource
中的项目。这就是为什么我们不能简单地使用多选
ListBox
的原因,其中
SelectedItems
必须是
Items
/
ItemsSource
的子集。在我们的用法中,情况并非如此。
Items
/
ItemsSource
,也不拥有
Members
集合,因此我们不能简单地将
IsMember
属性添加到项并绑定(bind)到该项。另外,无论如何这将是一个糟糕的设计,因为它将项目限制为属于一个单一成员。考虑其中十个控件的情况,所有控件都绑定(bind)到相同的
ItemsSource
,但具有十个不同的成员资格集合。
MembershipListItem
是
MembershipList
控件的容器)...
<Style TargetType="{x:Type local:MembershipListItem}">
<Setter Property="IsMember">
<Setter.Value>
<MultiBinding Converter="{StaticResource MembershipTest}">
<Binding /> <!-- Passes the DataContext to the converter -->
<Binding Path="Members" RelativeSource="{RealtiveSource AncestorType={x:Type local:MembershipList}}" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
Members
属性更改时,该值将通过
MembershipTest
转换器传递,并将结果存储在目标对象的
IsMember
属性中。
Members
集合中或从中删除,则绑定(bind)当然不会更新,因为集合实例本身并未更改,仅其内容已更改。
Count
添加额外的绑定(bind)。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
<Style TargetType="{x:Type local:MembershipListItem}">
<Setter Property="IsMember">
<Setter.Value>
<MultiBinding Converter="{StaticResource MembershipTest}">
<Binding /> <!-- Passes the DataContext to the converter -->
<Binding Path="Members" RelativeSource="{RealtiveSource AncestorType={x:Type local:MembershipList}}" />
<Binding Path="Members.Count" FallbackValue="0" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
MarkupExtension
,在返回实际绑定(bind)之前内部订阅了
CollectionChanged
集合的
Members
事件,以为我可以在事件处理程序中使用前面提到的
BindingExpression.UpdateTarget()
方法调用,但是问题是我没有目标从中获取
BindingExpression
的对象,以便从
UpdateTarget()
覆盖内调用
ProvideValue()
。换句话说,我知道我必须告诉某人,但我不知道该告诉谁。
CollectionChanged
事件的监听器目标,这会在容器开始虚拟化时引起问题,这就是为什么最好只使用绑定(bind)的原因当回收容器时,它将自动正确地重新应用。但是,您又回到了这个问题的开始,即无法告诉绑定(bind)更新以响应
CollectionChanged
通知。
DependencyProperty
事件使用第二个
CollectionChanged
CollectionChanged
的任意属性,将其添加到
MultiBinding
中,然后在每次您想要刷新绑定(bind)时进行更改。
DependencyProperty
的 bool
MembersCollectionChanged
。然后,在
Members_PropertyChanged
处理程序中,我订阅(或取消订阅)
CollectionChanged
事件,在该事件的处理程序中,我切换
MembersCollectionChanged
属性,以刷新
MultiBinding
。
public static readonly DependencyProperty MembersCollectionChangedProperty = DependencyProperty.Register(
"MembersCollectionChanged",
typeof(bool),
typeof(MembershipList),
new PropertyMetadata(false));
public bool MembersCollectionChanged
{
get { return (bool)GetValue(MembersCollectionChangedProperty); }
set { SetValue(MembersCollectionChangedProperty, value); }
}
public static readonly DependencyProperty MembersProperty = DependencyProperty.Register(
"Members",
typeof(ObservableCollection<object>),
typeof(MembershipList),
new PropertyMetadata(null, Members_PropertyChanged)); // Added the change handler
public int Members
{
get { return (int)GetValue(MembersProperty); }
set { SetValue(MembersProperty, value); }
}
private static void Members_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var oldMembers = e.OldValue as ObservableCollection<object>;
var newMembers = e.NewValue as ObservableCollection<object>;
if(oldMembers != null)
oldMembers.CollectionChanged -= Members_CollectionChanged;
if(newMembers != null)
oldMembers.CollectionChanged += Members_CollectionChanged;
}
private static void Members_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
// 'Toggle' the property to refresh the binding
MembersCollectionChanged = !MembersCollectionChanged;
}
Note: To avoid a memory leak, the code here really should use a
WeakEventManager
for theCollectionChanged
event. However I left it out because of brevity in an already long post.
<Style TargetType="{x:Type local:MembershipListItem}">
<Setter Property="IsMember">
<Setter.Value>
<MultiBinding Converter="{StaticResource MembershipTest}">
<Binding /> <!-- Passes in the DataContext -->
<Binding Path="Members" RelativeSource="{RealtiveSource AncestorType={x:Type local:MembershipList}}" />
<Binding Path="MembersCollectionChanged" RelativeSource="{RealtiveSource AncestorType={x:Type local:MembershipList}}" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
MembersCollectionChanged
),从而使您的API困惑。也就是说,从技术上讲,它确实满足要求。这样子感觉很脏。
INotifyPropertyChanged
INotifyPropertyChanged
的解决方案。这使得
MembershipList
也支持
INotifyPropertyChanged
。我将
Members
更改为标准CLR类型的属性,而不是
DependencyProperty
。然后,我在setter中订阅其
CollectionChanged
事件(并取消订阅旧的)。然后,只需在
PropertyChanged
事件触发时为
Members
引发
CollectionChanged
事件即可。
private ObservableCollection<object> _members;
public ObservableCollection<object> Members
{
get { return _members; }
set
{
if(_members == value)
return;
// Unsubscribe the old one if not null
if(_members != null)
_members.CollectionChanged -= Members_CollectionChanged;
// Store the new value
_members = value;
// Wire up the new one if not null
if(_members != null)
_members.CollectionChanged += Members_CollectionChanged;
RaisePropertyChanged(nameof(Members));
}
}
private void Members_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
RaisePropertyChanged(nameof(Members));
}
Again, this should be changed to use the
WeakEventManager
.
DependencyObject
也支持
INotifyPropertyChanged
接口(interface)是一个好主意。我不确定。我还没有发现任何表示不允许的内容,我的理解是
DependencyProperty
实际上会引发自己的更改通知,而不是应用/附加的
DependencyObject
,因此它们不应冲突。
INotifyCollectionChanged
接口(interface)并引发
PropertyChanged
的
DependencyProperty
事件的原因。如果在
DependencyProperty
上设置了绑定(bind),则它根本不会监听对象的
PropertyChanged
通知。没发生什么事。它落在耳朵上。要使用
INotifyPropertyChanged
,您必须将该属性实现为标准CLR属性。这就是我在上面的代码中所做的,再次可以正常工作。
PropertyChanged
引发
DependencyProperty
事件而实际上不更改值(如果可能的话)。我开始认为不是。
最佳答案
第二种选择是您的集合还实现INotifyPropertyChanged
,这是解决此问题的好方法。这很容易理解,代码并没有真正地“隐藏”在任何地方,它使用了所有XAML开发人员和您的团队熟悉的元素。
第一个解决方案也很不错,但是如果未对其进行很好的注释或记录,则某些开发人员可能会难以理解它的目的,或者甚至在以下情况时就知道它的存在:a)出现问题或b)他们需要将该控件的行为复制到其他地方。
由于这两者都起作用,而实际上是代码的“可读性”成为您的问题,因此,除非其他因素(性能等)成为问题,否则应以最具可读性的方式进行。
因此,选择解决方案B,请确保对其进行了适当的注释/记录,并确保您的团队知道解决此问题的方向。
关于c# - 是否可以强制基于DependencyProperty的绑定(bind)以编程方式重新评估?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32812948/
我正在尝试打印 timeval 类型的值。实际上我可以打印它,但我收到以下警告: 该行有多个标记 格式“%ld”需要“long int”类型,但参数 2 的类型为“struct timeval” 程序
我正在编写自己的 unix 终端,但在执行命令时遇到问题: 首先,我获取用户输入并将其存储到缓冲区中,然后我将单词分开并将它们存储到我的 argv[] 数组中。IE命令是“firefox”以启动存储在
我是 CUDA 的新手。我有一个关于一个简单程序的问题,希望有人能注意到我的错误。 __global__ void ADD(float* A, float* B, float* C) { con
我有一个关于 C 语言 CGI 编程的一般性问题。 我使用嵌入式 Web 服务器来处理 Web 界面。为此,我在服务器中存储了一个 HTML 文件。在此 HTML 文件中包含 JavaScript 和
**摘要:**在代码的世界中,是存在很多艺术般的写法,这可能也是部分程序员追求编程这项事业的内在动力。 本文分享自华为云社区《【云驻共创】用4种代码中的艺术试图唤回你对编程的兴趣》,作者: break
我有一个函数,它的任务是在父对象中创建一个变量。我想要的是让函数在调用它的级别创建变量。 createVariable testFunc() [1] "test" > testFunc2() [1]
以下代码用于将多个连续的空格替换为1个空格。虽然我设法做到了,但我对花括号的使用感到困惑。 这个实际上运行良好: #include #include int main() { int ch, la
我正在尝试将文件写入磁盘,然后自动重新编译。不幸的是,某事似乎不起作用,我收到一条我还不明白的错误消息(我是 C 初学者 :-)。如果我手动编译生成的 hello.c,一切正常吗?! #include
如何将指针值传递给结构数组; 例如,在 txt 上我有这个: John Doe;xxxx@hotmail.com;214425532; 我的代码: typedef struct Person{
我尝试编写一些代码来检索 objectID,结果是 2B-06-01-04-01-82-31-01-03-01-01 . 这个值不正确吗? // Send a SysObjectId SNMP req
您好,提前感谢您的帮助, (请注意评论部分以获得更多见解:即,以下示例中的成本列已添加到此问题中;西蒙提供了一个很好的答案,但成本列本身并未出现在他的数据响应中,尽管他提供的功能与成本列一起使用) 我
我想知道是否有人能够提出一些解决非线性优化问题的软件包的方法,而非线性优化问题可以为优化解决方案提供整数变量?问题是使具有相等约束的函数最小化,该函数受某些上下边界约束的约束。 我已经在R中使用了'n
我是 R 编程的初学者,正在尝试向具有 50 列的矩阵添加一个额外的列。这个新列将是该行中前 10 个值的平均值。 randomMatrix <- generateMatrix(1,5000,100,
我在《K&R II C 编程 ANSI C》一书中读到,“>>”和“0; nwords--) sum += *buf++; sum = (sum >>
当下拉列表的选择发生变化时,我想: 1) 通过 div 在整个网站上显示一些 GUI 阻止覆盖 2)然后处理一些代码 3) 然后隐藏叠加层。 问题是,当我在事件监听器函数中编写此逻辑时,将执行 onC
我正在使用 Clojure 和 RESTEasy 设计 JAX-RS REST 服务器. 据我了解,用 Lisp 系列语言编写的应用程序比用“传统”命令式语言编写的应用程序更多地构建为“特定于领域的语
我目前正在研究一种替代出勤监控系统作为一项举措。目前,我设计的用户表单如下所示: Time Stamp Userform 它的工作原理如下: 员工将选择他/她将使用的时间戳类型:开始时间、超时、第一次
我是一名学生,试图自学编程,从在线资源和像您这样的人那里获得帮助。我在网上找到了一个练习来创建一个小程序来执行此操作: 编写一个程序,读取数字 a 和 b(长整型)并列出 a 和 b 之间有多少个数字
我正在尝试编写一个 shell 程序,给定一个参数,打印程序的名称和参数中的每个奇数词(即,不是偶数词)。但是,我没有得到预期的结果。在跟踪我的程序时,我注意到,尽管奇数词(例如,第 5 个词,5 %
只是想知道是否有任何 Java API 可以让您控制台式机/笔记本电脑外壳上的 LED? 或者,如果不可能,是否有可能? 最佳答案 如果你说的是前面的 LED 指示电源状态和 HDD 繁忙状态,恐怕没
我是一名优秀的程序员,十分优秀!