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

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

问题描述

我有一个对象,不能继承的DependencyObject或使用NotifyPropertyChanged,我已经将它绑定到相当多的管制,所以当属性发生改变,我不想去每一个控制和改变它的价值在code,所以我想必须有一个方法来告诉XAML为重新绑定所有,它的绑定到code的一行或两行,而不是去:

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;

等等,等等...

So on, so forth...

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

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天气的一个新实例,它需要相同的参考(这就是为什么我把它设置为空,因此它的变化):

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;
}

在此先感谢!

推荐答案

如果你有机会获得你要更新绑定,那么你可以明确地更新绑定的元素。您可以检索的元素绑定防爆pression然后用UpdateTarget()刷新界面,或UpdateSource刷新后盾属性(如果要绑定的东西像编辑一个文本框)。

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的,虽然如果在所有可能的。这样,你可以从中提取code背后的逻辑。)

(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天全站免登陆