XAML:更改DataContext时更新绑定

时间:2011-07-04 11:23:25

标签: c# wpf xaml data-binding

我有一个简单的XAML文件,它包含一个Label,其Foreground属性包含一个绑定:

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Width="200" Height="100" >
    <Label Content="Sampletext" Foreground="{Binding Path=Color}" />
</Grid>

当我加载模板并应用DataContext时,Foreground仍然具有默认值。 是否可以获得绑定的前景值而不渲染网格?

// Load template
string templatePath = "/WpfApplication1;component/Template.xaml";
Grid grid = Application.LoadComponent(new Uri(templatePath, UriKind.Relative)) as Grid;

// Set dataContext
grid.DataContext = new { Color = Brushes.Green };

// Foregound still has default value
var foreground = ((Label)grid.Children[0]).Foreground;

可以在此处下载项目:http://dl.dropbox.com/u/21096596/WpfApplication1.zip

5 个答案:

答案 0 :(得分:2)

尝试

lblName.GetBindingExpression(Label.ForegroundProperty).UpdateTarget();

var foreground = ((Label)grid.Children[0]).Foreground;

答案 1 :(得分:1)

有自动DataContext更改通知,如果满足必要条件,绑定将更新。其中之一是加载了控件(IsLoaded == true),这在代码中并非如此。只有在您将UI添加到UI的某个位置时,控件才会加载。

示例测试代码:

private void Button_Click(object sender, RoutedEventArgs e)
{
    Grid grid = null;
    Action action = () =>
        {
            var foreground = ((Label)grid.Children[0]).Foreground;
            MessageBox.Show(foreground.ToString());

            grid.DataContext = new { Color = Brushes.Green };

            foreground = ((Label)grid.Children[0]).Foreground;
            MessageBox.Show(foreground.ToString());
        };
    grid = Application.LoadComponent(new Uri("Stuff/GridOne.xaml", UriKind.Relative)) as Grid;
    if (grid.IsLoaded)
    {
        action();
    }
    else
    {
        grid.Loaded += (s, _) => action();
    }
    // This adds the grid to some StackPanel, if you do not do something like this
    // nothing will happen since the control will not be loaded and thus the event
    // will not fire, etc. 
    ControlStack.Children.Add(grid);
}

答案 2 :(得分:0)

为什么需要一次性绑定?删除它,它应该工作。

答案 3 :(得分:0)

DataContext包裹在一个对象中,并实现INotifyPropertyChanged,然后绑定将在属性更改时更新,并且无需手动更新绑定:

public class MyDataContext : INotifyPropertyChanged 
{
    private Brush color;
    public Brush Color
    {
        get { return color; }
        set
        {
            color = value;
            RaisePropertyChanged("Color");
        }
    }

    //implementation of PropertyChanged and RaisePropertyChanged omitted
}

然后像这样更新它:

var dc = new MyDataContext();
grid.DataContext = dc;
dc.Color = Brushes.Green; //this will trigger the NotifyPropertyChanged and update the binding
//color should be changed now
var foreground = ((Label)grid.Children[0]).Foreground;

希望这会有所帮助......

答案 4 :(得分:0)

如果希望将控件的属性绑定到DataContext的属性,但要在运行时更改datacontext,则有一种更简单的方法。 创建一个ContentControl,然后使用ContentControl.ContentTemplate

        <ContentControl Content=something>
            <ContentControl.ContentTemplate>
                <DataTemplate>
                    <Label Foreground="{Binding Path=Color}" />
                </DataTemplate>
            </ContentControl.ContentTemplate>
        </ContentControl>

更改ContentControl的内容,而不是更改Label的DataContext。