WPF 强制重新绑定 [英] WPF Force rebind

查看:27
本文介绍了WPF 强制重新绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个不能继承DependencyObject或使用NotifyPropertyChanged的对象,而且我已经绑定了很多控件,所以当属性改变时,我不想去每个控件并改变它的值代码,所以我认为必须有一种方法来告诉 XAML 用一两行代码重新绑定"它所绑定的所有内容,而不是去:

I have an object that can't inherit DependencyObject OR use NotifyPropertyChanged, and I've binded it to quite a few controls, so when the properties change, I don't want to go to each control and change it's value on the code, so I'm thinking there must be a way to tell the XAML to "Rebind" all that it's bound to with one or two lines of code, instead of going:

label1.Content = myObject.DontNotifyThis;
label2.Content = myObject.DontNotifyThisEither;
label3.Content = myObject.DontEvenThinkOfNotifyingThis;
label4.Content = myObject.NotSoFastPal;

依此类推...

这是一个过于简单的例子:

This is an oversimplified example:

XAML:

<Window x:Class="StackOverflowTests.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" x:Name="window1" Height="300" Width="300" Loaded="window1_Loaded">
    <Grid x:Name="gridMain">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Label Grid.Row="0" Content="{Binding Status}" ContentStringFormat="Today's weather: {0}" />
        <Label Grid.Row="2" Content="{Binding Temperature}" ContentStringFormat="Today's temperature: {0}" />
        <Label Grid.Row="1" Content="{Binding Humidity}" ContentStringFormat="Today's humidity: {0}" />
    </Grid>
</Window>

C#:

using System.Windows;

namespace StackOverflowTests
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        Weather weather = new Weather("Cloudy", "60F", "25%");

        public Window1()
        {
            InitializeComponent();
            this.DataContext = weather;
        }

        private void window1_Loaded(object sender, RoutedEventArgs e)
        {
            weather.Status = "Sunny";
            weather.Temperature = "80F";
            weather.Humidity = "3%";
        }       
    }

    class Weather
    {
        public string Status { get; set; }
        public string Temperature { get; set; }
        public string Humidity { get; set; }

        public Weather(string status, string temperature, string humidity)
        {
            this.Status = status;
            this.Temperature = temperature;
            this.Humidity = humidity;
        }
    }
}

我找到了一种方法,但它一点也不优雅,不幸的是,我不能将 DataContext 设置为新的天气实例,它需要是相同的引用(这就是我将其设置为的原因)null 所以它会改变):

I found a way to do it, but it's not elegant at all, and unfortunatelly, I can't just set the DataContext to a new instance of weather, it needs to be the SAME reference (that's why I set it to null so it changes):

private void window1_Loaded(object sender, RoutedEventArgs e)
{
    weather.Status = "Sunny";
    weather.Temperature = "80F";
    weather.Humidity = "3%";

    // bad way to do it
    Weather w = (Weather)this.DataContext;
    this.DataContext = null;
    this.DataContext = w;
}   

提前致谢!

推荐答案

如果您有权访问要更新绑定的元素,那么您可以显式更新绑定.您可以检索元素上的绑定表达式,然后使用 UpdateTarget() 刷新 UI,或使用 UpdateSource 刷新支持属性(如果您想绑定到诸如 TextBox 之类的可编辑内容).

If you have access to the element that you want to update the binding on then you can explicitly update the binding. You can retrieve the Binding Expression on the element and then use UpdateTarget() to refresh the UI, or UpdateSource to refresh the backing property (if you want to bind to something editable like a TextBox).

这是一个简单的例子来演示它:

Here's a simple example that demonstrates it:

<StackPanel>
    <TextBlock x:Name="uiTextBlock" Text="{Binding MyString}" />
    <Button Click="Button_Click"
            Content="Rebind" />
</StackPanel>

public partial class Window1 : Window
{
    public string MyString { get; set; }

    public Window1()
    {
        MyString = "New Value";

        InitializeComponent();
        this.DataContext = this;
    }
    int count = 0;
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        MyString = "Rebound " + ++count + " times";

        var bindingExpression = uiTextBlock.GetBindingExpression(TextBlock.TextProperty);
        bindingExpression.UpdateTarget();
    }
}

(如果可能的话,我建议使用 INotifyPropertyChanged.这样你就可以从后面的代码中提取逻辑.)

(I would recommend using INotifyPropertyChanged though if at all possible. That way you can extract the logic from the code behind.)

这篇关于WPF 强制重新绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆