简体   繁体   中英

Binding to Control does not update when property changes

I am using a Binding + IValueConverter bound directly to a control to produce a result that is calculated using multiple properties on the control. Is there any way to have the converter called whenever a property on the control changes?

I know it is possible to use an IMultiValueConverter to bind to the properties I want, but this takes up a lot of space in the code and breaks the flow.

Example Code:

MainWindow.xaml

<Window x:Class="BindingToFrameworkElement.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:BindingToFrameworkElement"
        Title="MainWindow" Height="350" Width="525">
  <Window.Resources>
    <local:ElementConverter x:Key="ElementConverter"/>
  </Window.Resources>
  <Grid>
    <TextBlock Text="{Binding ElementName=B, Converter={StaticResource ElementConverter}}"/>
    <Button Name="B" Click="Button_Click" Width="50" Height="20">Hello</Button>
  </Grid>
</Window>

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace BindingToFrameworkElement
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            B.Width += 20;
        }
    }

    public class ElementConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            FrameworkElement element = value as FrameworkElement;

            return element.ActualWidth + element.ActualHeight;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

Binding to properties, as long as they are dependncy properties, is the simples solution so as to learn that some change occured.
If you want to go beyond border you can create dependency property listener and when specifiec properties are altered send some Message, using for instance MVVM Light. Then catch this Message wherever you want to update some data based on changed DP. Anyway, I would not counsel you to take such a sofisticated steps.

By the way, you set binding to Button and since button is UI element then as a result converter will be invoked once and never again, keep that in mind.
Create another folder, name it Converters and place them all classess which derive either IValueConverter or IMultiValueConverter. Such a step allows you to acquire distinct separation and additionaly you do not mess your code-behind file with irrelevant code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM