In general, Bindings are a very handy way of connecting data in C# with its visual representation in Xaml. When the data changes, the Visual Representation automatically updates as well. However, in a case where you have thousands of bindings, and most of them are on pages that aren't on the screen right now, it seems silly and expensive to keep all the hidden visual representations up to date. But as you can see if you run the example below, that is exactly what a binding does by default! Even when I remove CountingBlock
from the screen, it keeps on calling my BreakpointConverter
every time the Counter
updates.
To me, it makes more sense to stop updating while Unloaded, and then as part of the LoadedEvent, reactivate all my bindings, checking for what the source has been updated to in the meantime. Is there a way to accomplish this?
Thanks,
The Xaml:
<Window x:Class="DeactivateBindings.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="450" Width="800">
<UniformGrid>
<ContentControl Name="Container"/>
<Button Content="Show or Hide" Click="ShowOrHide_Click"/>
</UniformGrid>
</Window>
The Converter:
class BreakpointConverter : System.Windows.Data.IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value; // does nothing, but you can set a breakpoint here to see if the binding is active.
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
}
The Code Behind:
public partial class MainWindow : Window
{
bool _isCounterVisible;
Label CountingBlock = new Label { FontSize = 25 };
public MainWindow()
{
InitializeComponent();
ContingBlock.SetBinding(Label.ContentProperty, new Binding
{
Source = this,
Path = new PropertyPath(nameof(Counter)),
// this Converter is the key component that tells us the binding is still active, because we can breakpoint it.
Converter = new BreakpointConverter(),
});
StartCounting();
}
private async void StartCounting()
{
while(true)
{
Counter++;
await Task.Delay(500);
}
}
private void ShowOrHide_Click(object sender, RoutedEventArgs e)
{
_isCounterVisible = !_isCounterVisible;
Countainer.Content = _isCounterVisible ? CountingBlock : null;
}
public int Counter
{
get { return (int)GetValue(CounterProperty); }
set {SetValue(CounterProperty, value); }
}
public static readonly DependencyProperty CounterProperty =
DependencyProperty.Register(nameof(Counter), typeof(int), typeof(MainWindow), new PropertyMetadata(0));
}