Kann ich die Bindung eines ui-Elements verzögern, wenn das Element momentan nicht sichtbar ist. Manchmal habe ich ein Formular, das einige versteckte/minimierte Elemente enthält. Ich möchte sie nicht aktualisieren, wenn sie nicht auf dem Bildschirm angezeigt werden. Ich vermute, die Antwort ist nein, aber es tut nie weh zu fragen?WPF: Stoppen Sie die Bindung, wenn ein UI-Element nicht sichtbar ist
Antwort
Es gibt keine eingebaute Möglichkeit dies zu tun - aber Sie können es selbst schreiben.
Der Trick ist, verbindlich in Ihrer eigenen Markup Erweiterung zu wickeln, die die ursprüngliche Bindung verwenden sondern fügen neues Verhalten um sie (zum Beispiel durch Update auf explizite Einstellung, wenn Sie das nicht wollen, verbindlich zu arbeiten.
hier ist ein Beispiel (das verzögert die Bindung der Datenübertragung):
http://www.paulstovell.com/wpf-delaybinding
Nun gibt es eine Menge von möglichen Randbedingungen mit Bindings für unsichtbare Kontrollen zu deaktivieren, vor allem um zeigen und Kontrollen versteckt, so würde ich nicht schreibe eine generische Erweiterung dafür - aber darf In Ihrer spezifischen Anwendung kann dies nützlich sein.
das ist wierd, schrieb ich eine ähnliche Sache - http://www.codeproject.com/KB/WPF/DelayedBindingTextBox.aspx –
Die Antwort ist nein, weil die Bindung Ursache dafür sein könnte, ein Element wieder sichtbar zu machen. Wenn also die Bindung an verborgenen Steuerelementen nicht funktioniert, kann die Bindung nicht wieder sichtbar gemacht werden.
Für eine Problemumgehung habe ich eine Bindung an die Sichtbarkeit des Objekts, wenn das Objekt auf sichtbar gesetzt ist, löst die Eigenschaft die Konstruktion des Elements dahinter aus, die über eine ContentPresenter
Bindung verfügen.
Ich weiß, dass dies eine alte Frage ist, aber da ich keine implementierte Klasse oder etwas gefunden habe, habe ich es selbst gemacht, gefolgt von @Nir antwort.
Dies ist eine Markup-Erweiterung ist, die Bindung an nur wirklich binden normale wickelt, wenn das Objekt IsVisible
Eigenschaft zum ersten Mal wahr wird:
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();
}
}
}
}
zu benutzen:
<ItemsControl ItemsSource="{mx:LazyBinding Documents}"/>
In diesem Beispiel Es wird nur gebunden, wenn ItemsControl IsVisible
zum ersten Mal wahr wird.
Es wird nicht gelöst, wenn die IsVisible
wird wieder falsch, aber ich denke, jemand kann es bei Bedarf ändern.
Verbesserte MarkupExtension, die die normale Bindung an das automatische Bind/Binding-Datenmodell umschließt, wenn sie sichtbar geändert wurde.
Siehe vorherige Version 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
}
}
zu benutzen:
<ItemsControl ItemsSource="{utils:LazyBinding Documents}"/>
- 1. WPF MVVM Stopp-Timer, wenn die Ansicht nicht sichtbar ist
- 2. Animation stoppt, wenn ListBoxItem nicht sichtbar ist (WPF)
- 3. WPF UIElement Aktualisierungsfehler?
- 4. Bindung an UIElement in Code-Behind Absturz
- 5. Knockout sichtbar Bindung nicht funktioniert
- 6. WPF Horizontale Bildlaufleiste ist nicht sichtbar
- 7. Finden Sie die Mitte eines Uielement in Wpf
- 8. Wpf-Steuerelement ist nicht sichtbar, wenn die Anwendung eine Aufgabe erledigt, es erscheint, nachdem die Aufgabe abgeschlossen ist
- 9. Schließen Sie die Tastatur, wenn sie bereits sichtbar ist
- 10. WPF Bindung funktioniert nicht
- 11. Füllen Sie nicht DropDownList, wenn aufrechte UserControl nicht sichtbar ist
- 12. , wenn ein Element wirklich sichtbar ist
- 13. WPF Style-Trigger-on Foreign UIElement
- 14. Stoppen Sie die Pipeline, wenn die Phase instabil ist
- 15. jQuery Wenn ein Element sichtbar ist, schließen Sie das andere
- 16. WPF Tooltip Bindung nicht aktualisiert
- 17. WPF: DataBinding eine PointCollection für ein benutzerdefiniertes UIElement
- 18. WPF-Zweiwege-Bindung funktioniert nicht
- 19. Kann ich die angulare Bindung stillschweigend stoppen?
- 20. WPF - Feststellen, ob die Maus über einem UIElement
- 21. WPF-Kontrollkästchen Bindung funktioniert nicht
- 22. Meine Schaltfläche ist nicht sichtbar, wenn ich die Anwendung ausführen
- 23. Stoppen Sie den Dienst, wenn die App geschlossen ist
- 24. WPF - Kann ein animierendes Storyboard nicht stoppen, IsControllable funktioniert nicht?
- 25. Ansicht ist nicht sichtbar, wenn sie nichts zu zeigen hat?
- 26. So legen Sie eine Schaltfläche fest, die nur sichtbar ist, wenn ein Bedienfeld ausgeblendet ist
- 27. Wie fügt man der Eigenschaft von UIElement eine Bindung hinzu, ohne die Methode SetBinding()?
- 28. WPF Expander IsExpanded Bindung
- 29. So stoppen Sie die Randomisierung, wenn eine Bedingung erfüllt ist
- 30. WPF - Bindung an ein Menü-Symbol
warum sollten Sie das tun wollen? für die Leistung? –
ja Leistung, es ist eigentlich Faulheit (Faulheit ist die Mutter der Erfindung), weil ich Dinge aus dem Baum entfernen sollte, wenn sie nicht sichtbar sind, um die Leistung zu bekommen, die ich brauche. –