如果元素當前不可見,是否可以延遲UI元素的綁定?有時候我有一個表單有一些隱藏/最小化的元素,如果他們不在屏幕上,我想不更新它們。我懷疑答案是否定的,但它從不傷害要問嗎?WPF:如果UI元素不可見,則停止綁定
回答
沒有內置的方法來做到這一點 - 但你可以自己寫。
訣竅是包裝在使用原來的約束力,但它周圍增加了新的行爲(例如,通過UpdateSourceTrigger設置爲Explicit自己的標記擴展綁定時你不希望綁定工作要做。
下面是一個例子(即延遲綁定的數據傳輸):
http://www.paulstovell.com/wpf-delaybinding
現在,有很多與禁用綁定無形的控制,尤其是在顯示和隱藏控制可能的邊界條件,所以我不會爲此寫一個通用的擴展 - 但可能在你的具體應用中,這可能是有用的。
多數民衆贊成在奇怪的是,我寫了一個類似的東西 - http://www.codeproject.com/KB/WPF/DelayedBindingTextBox.aspx – 2010-02-16 05:39:36
答案是否定的,因爲綁定可能是導致元素再次可見的原因。因此,如果綁定不能在隱藏的控件上工作,它將不允許綁定再次使其可見。
解決方法我有一個綁定到對象的可見性,當對象設置爲可見時,該屬性觸發通過ContentPresenter
具有綁定後面的元素的構造。
我知道這是一個古老的問題,但由於我沒有找到實現的類或其他東西,我自己做了,遵循@Nir的答案。
這是一個標記擴展,它包裝正常結合到當對象IsVisible
屬性首次變爲真才真正地結合:
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();
}
}
}
}
要使用:
<ItemsControl ItemsSource="{mx:LazyBinding Documents}"/>
在這個例子中,它只會在ItemsControl IsVisible
第一次變爲true時綁定。
當IsVisible
再次失敗時,它不會解除綁定,但我認爲有人可以根據需要進行更改。
改進的MarkupExtension包裝普通的綁定,以在可見變化時自動綁定/取消綁定數據模型。
參見以前的版本here。
using System;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using System.Windows.Markup;
namespace UtilsWPF
{
[MarkupExtensionReturnType(typeof(object))]
public class LazyBindingExtension : MarkupExtension
{
public LazyBindingExtension()
{ }
public LazyBindingExtension(PropertyPath path) : this()
{
Path = path;
}
#region Properties
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 UIElement bindingTarget;
private DependencyProperty bindingTargetProperty;
#endregion
#region Init
public override object ProvideValue(IServiceProvider serviceProvider)
{
var valueProvider = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
if (valueProvider != null)
{
bindingTarget = valueProvider.TargetObject as UIElement;
if (bindingTarget == null)
{
throw new NotSupportedException($"Target '{valueProvider.TargetObject}' is not valid for a LazyBinding. The LazyBinding target must be a UIElement.");
}
bindingTargetProperty = valueProvider.TargetProperty as DependencyProperty;
if (bindingTargetProperty == null)
{
throw new NotSupportedException($"The property '{valueProvider.TargetProperty}' is not valid for a LazyBinding. The LazyBinding 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()
{
bindingTarget.IsVisibleChanged += UiElement_IsVisibleChanged;
updateBinding();
return bindingTarget.GetValue(bindingTargetProperty);
}
#endregion
#region Event Handlers
private void UiElement_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
updateBinding();
}
#endregion
#region Update Binding
private void updateBinding()
{
if (bindingTarget.IsVisible)
{
ConsolidateBinding();
}
else
{
ClearBinding();
}
}
private bool _isBind;
private void ConsolidateBinding()
{
if (_isBind)
{
return;
}
_isBind = true;
BindingOperations.SetBinding(bindingTarget, bindingTargetProperty, binding);
}
private void ClearBinding()
{
if (!_isBind)
{
return;
}
BindingOperations.ClearBinding(bindingTarget, bindingTargetProperty);
_isBind = false;
}
#endregion
}
}
要使用:
<ItemsControl ItemsSource="{utils:LazyBinding Documents}"/>
- 1. iOS UI元素不可見
- 2. WPF綁定停止
- 3. 如何綁定UI元素?
- 4. WPF綁定停止負載
- 5. WPF元素綁定
- 6. WPF元素綁定與動態生成的UI元素
- 7. Kendo UI可見綁定不起作用
- 8. 如果元素在量角器中不可見,則繼續
- 9. 如果元素不完全可見,則滾動到元素的末尾
- 10. ExpectedConditions.invisibilityOfElementLocated在只有一個元素不可見時停止?
- 11. Angular2表演元素,如果沒有特定的元素可見
- 12. Firefox不規則元素的可見性
- 13. WPF元素屬性綁定
- 14. 綁定不更新多個UI元素
- 15. 元素不可見
- 16. 元素不可見
- 17. WPF基於組合選擇的UI元素的可見性
- 18. WPF TreeView綁定不添加元素
- 19. 如何停止可拖動元素Jquery Ui的調整大小?
- 20. 如果在頁面上找不到該元素,則綁定jQuery元素中斷?
- 21. WPF Element.Effect,停止影響子元素?
- 22. 如何停止渲染不可見面
- 23. 檢查哪些元素在視口中可見(不是如果特定元素可見)
- 24. 如果可見元素的值大於0,則影響元素的樣式
- 25. jQuery - 如果其他元素變得可見,則更改元素高度
- 26. 當數據綁定到漸變停止時,找不到可視樹元素
- 27. 使元素可見後訪問WPF DataGrid
- 28. WPF畫布中的可見元素
- 29. ASP使不可見元素可見
- 30. 如何停止knockout.js綁定評估的子元素
你爲什麼要這麼做?表現? – 2010-02-10 01:43:36
是的表現,它的實際懶惰(懶惰是發明之母),因爲如果它們不可見,我應該從樹上移除東西,以獲得我需要的性能。 – 2010-02-10 02:22:26