Ara*_*and 20 data-binding wpf visibility
如果元素当前不可见,我可以延迟ui元素的绑定.有时我的表单有一些隐藏/最小化的元素,如果它们不在屏幕上,我不想更新它们.我怀疑答案是否定的,但问问题从来没有伤害过?
我知道这是一个老问题,但由于我找不到实现的类或其他东西,我按照@Nir 的回答自己做了。
这是一个标记扩展,它将普通绑定包装为仅在对象IsVisible属性第一次变为 true 时才真正绑定:
using System;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using System.Windows.Markup;
namespace MakupExtensions {
[MarkupExtensionReturnType(typeof(object))]
public class LazyBindingExtension : MarkupExtension {
public LazyBindingExtension() {
}
public LazyBindingExtension(PropertyPath path) : this() {
Path = path;
}
public IValueConverter Converter {
get;
set;
}
[TypeConverter(typeof(CultureInfoIetfLanguageTagConverter))]
public CultureInfo ConverterCulture {
get;
set;
}
public object ConverterParamter {
get;
set;
}
public string ElementName {
get;
set;
}
[ConstructorArgument("path")]
public PropertyPath Path {
get;
set;
}
public RelativeSource RelativeSource {
get;
set;
}
public object Source {
get;
set;
}
public UpdateSourceTrigger UpdateSourceTrigger {
get;
set;
}
public bool ValidatesOnDataErrors {
get;
set;
}
public bool ValidatesOnExceptions {
get;
set;
}
public bool ValidatesOnNotifyDataErrors {
get;
set;
}
private Binding binding;
private DependencyObject bindingTarget;
private DependencyProperty bindingTargetProperty;
public override object ProvideValue(IServiceProvider serviceProvider) {
var valueProvider = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
if (valueProvider != null) {
bindingTarget = valueProvider.TargetObject as DependencyObject;
bindingTargetProperty = valueProvider.TargetProperty as DependencyProperty;
if (bindingTargetProperty == null || bindingTarget == null) {
throw new NotSupportedException($"The property '{valueProvider.TargetProperty}' on target '{valueProvider.TargetObject}' is not valid for a LazyBinding. The LazyBinding target must be a DependencyObject, and the target property must be a DependencyProperty.");
}
binding = new Binding {
Path = Path,
Converter = Converter,
ConverterCulture = ConverterCulture,
ConverterParameter = ConverterParamter
};
if (ElementName != null) {
binding.ElementName = ElementName;
}
if (RelativeSource != null) {
binding.RelativeSource = RelativeSource;
}
if (Source != null) {
binding.Source = Source;
}
binding.UpdateSourceTrigger = UpdateSourceTrigger;
binding.ValidatesOnDataErrors = ValidatesOnDataErrors;
binding.ValidatesOnExceptions = ValidatesOnExceptions;
binding.ValidatesOnNotifyDataErrors = ValidatesOnNotifyDataErrors;
return SetBinding();
}
return null;
}
public object SetBinding() {
var uiElement = bindingTarget as UIElement;
if (uiElement != null && !uiElement.IsVisible) {
uiElement.IsVisibleChanged += UiElement_IsVisibleChanged;
}
else {
ConsolidateBinding();
}
return bindingTarget.GetValue(bindingTargetProperty);
}
private void ConsolidateBinding() => BindingOperations.SetBinding(bindingTarget, bindingTargetProperty, binding);
private void UiElement_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) {
var uiElement = sender as UIElement;
if (uiElement != null && uiElement.IsVisible) {
uiElement.IsVisibleChanged -= UiElement_IsVisibleChanged;
ConsolidateBinding();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用方法:
<ItemsControl ItemsSource="{mx:LazyBinding Documents}"/>
Run Code Online (Sandbox Code Playgroud)
在此示例中,仅当 ItemsControlIsVisible第一次变为 true 时才会绑定。
当再次变为 false 时,它不会解除绑定IsVisible,但我认为有人可以根据需要更改它。
没有内置的方法可以做到这一点 - 但您可以自己编写。
诀窍是将绑定包装在您自己的标记扩展中,该标记扩展使用原始绑定,但在其周围添加新行为(例如,当您不希望绑定工作时,将 UpdateSourceTrigger 设置为 Explicit。
这是一个示例(延迟绑定的数据传输):
http://www.paulstovell.com/wpf-delaybinding
现在,有很多可能的边缘条件会禁用不可见控件的绑定,特别是在显示和隐藏控件方面,因此我不会为此编写通用扩展 - 但也许在您的特定应用程序中这可能很有用。
| 归档时间: |
|
| 查看次数: |
5815 次 |
| 最近记录: |