XAML: обновить привязку при изменении DataContext - PullRequest
3 голосов
/ 04 июля 2011

У меня есть простой XAML-файл, он содержит метку, свойство Foreground которой содержит привязку:

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

Когда я загружаю шаблон и применяю DataContext, передний план все еще имеет значение по умолчанию. Можно ли получить привязанное значение переднего плана без рендеринга сетки?

// 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

Ответы [ 4 ]

2 голосов
/ 04 июля 2011

попробуй

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

до

var foreground = ((Label)grid.Children[0]).Foreground;
1 голос
/ 04 июля 2011

Имеются автоматические DataContext уведомления об изменении, привязка обновится, если будут выполнены необходимые условия.Одним из них является то, что элемент управления загружен (IsLoaded == true), что не так в вашем коде.Элемент управления будет загружаться только в том случае, если вы добавите его в свой пользовательский интерфейс где-нибудь.

Пример тестового кода:

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);
}
0 голосов
/ 04 июля 2011

Оберните 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;

Надеюсь, это поможет ...

0 голосов
/ 04 июля 2011

Зачем вам нужен одноразовый переплет? удалите это, и оно должно работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...