Привязка текста заголовка сетки данных WPF

Заголовок столбца DataGrid по какой-то причине не является элементом FrameWork, и поэтому вы не можете использовать привязки для установки таких вещей, как текст заголовка. Пожалуйста, исправьте меня, если это не так, если это изменилось в.NET 4.0 (сейчас я использую последнюю версию WPFToolkit от CodePlex).

Я пытаюсь использовать DataGrid для представления расписания, где дата дня должна быть частью текста заголовка (т. Е. "Sun, Nov 01"), и в моем XAML есть следующее:

        <dg:DataGrid.Columns>
        <dg:DataGridTextColumn Header="Description" Width="Auto" Binding="{Binding Description}" IsReadOnly="True"/>
        <dg:DataGridTextColumn Header="Mon" Width="50" Binding="{Binding Allocations[0].Amount}"  />
... every other day of the week ....
        <dg:DataGridTextColumn Header="Sun" Width="50" Binding="{Binding Allocations[6].Amount}"  />
        <dg:DataGridTextColumn Header="Total" MinWidth="50" Binding="{Binding TotalAllocatedAmount}" IsReadOnly="True" />
    </dg:DataGrid.Columns>

Я хотел бы использовать тот же AllocationViewModel, который я использую для данных (т. Е. "{Binding Allocations[0].Amount}", и связать его свойство DisplayName с текстом заголовка. Может кто-нибудь показать мне, как это сделать? Если у меня есть использовать статический ресурс, как я могу получить DataContext там?

РЕДАКТИРОВАТЬ ---------------- ПРЕДПОЧТИТЕЛЬНАЯ РАБОТА ВОКРУГ

Некоторое время назад Джош Смит писал о DataContextSpy, и это самый чистый обходной путь, с которым я столкнулся в этой проблеме. Вот класс, который заставляет это работать:

/// <summary>
/// Workaround to enable <see cref="DataContext"/> bindings in situations where the DataContext is not redily available. 
/// </summary>
/// <remarks>http://blogs.infragistics.com/blogs/josh_smith/archive/2008/06/26/data-binding-the-isvisible-property-of-contextualtabgroup.aspx</remarks>
public class DataContextSpy : Freezable
{
    public DataContextSpy()
    {
        // This binding allows the spy to inherit a DataContext.
        BindingOperations.SetBinding(this, DataContextProperty, new Binding());
    }

    public object DataContext
    {
        get { return GetValue(DataContextProperty); }
        set { SetValue(DataContextProperty, value); }
    }

    // Borrow the DataContext dependency property from FrameworkElement.
    public static readonly DependencyProperty DataContextProperty = FrameworkElement
        .DataContextProperty.AddOwner(typeof (DataContextSpy));

    protected override Freezable CreateInstanceCore()
    {
        // We are required to override this abstract method.
        throw new NotImplementedException();
    }
}

Имея это, я могу перехватить нужный мне DC в xaml:

    <dg:DataGrid.Resources>
        <behavior:DataContextSpy x:Key="spy" DataContext="{Binding Allocations}" />
    </dg:DataGrid.Resources>

И затем примените по мере необходимости через связывание:

            <dg:DataGridTextColumn Header="{Binding Source={StaticResource spy}, Path=DataContext[0].DisplayName}" 
                               Width="50" Binding="{Binding Allocations[0].Amount}"  />

Suh-Weet!

8 ответов

Это простой способ привязать заголовок DataGridTextColumn к контексту данных:

<DataGrid x:Name="summaryGrid" Grid.Row="3" AutoGenerateColumns="False" IsReadOnly="True" CanUserAddRows="False">
       <DataGrid.Columns>
            <DataGridTextColumn Header="Hard Coded Title" Width="*"/>
            <DataGridTextColumn Width="100">
                <DataGridTextColumn.Header>
                    <TextBlock Text="{Binding DataContext.SecondColumnTitle, 
                                              RelativeSource={RelativeSource AncestorType={x:Type local:MainWindow}}}"/>
                </DataGridTextColumn.Header>
            </DataGridTextColumn>
            <DataGridTextColumn Width="150">
                <DataGridTextColumn.Header>
                    <TextBlock Text="{Binding DataContext.ThirdColumnTitle, 
                                              RelativeSource={RelativeSource AncestorType={x:Type local:MainWindow}}}"/>
                </DataGridTextColumn.Header>
            </DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>

Очевидно, вам понадобятся свойства: SecondColumnTitle а также ThirdColumnTitle реализовано в вашем классе контекста данных.

У меня есть это решение, работающее в.net 4.5, и у меня не было ни шансов, ни причин попробовать его в более ранних версиях фреймворка.

Я знаю, что этот пост старый, но когда я посмотрел, как это сделать, появилась первая запись. Мне не понравился этот ответ, потому что он казался излишним. После дополнительных поисков я натолкнулся на эту ссылку и показал, как это сделать в разметке, используя столбец шаблона.

<DataGridTemplateColumn>
    <DataGridTemplateColumn.HeaderTemplate>
        <DataTemplate>
            **<TextBlock Text="{Binding DataContext.HeaderTitle, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />**
        </DataTemplate>
    </DataGridTemplateColumn.HeaderTemplate>
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding}" Width="200" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

Я решил это с помощью HeaderTemplate и привязка к DataContext из DataGrid, с помощью RelativeSource.

<DataGrid ItemsSource="{Binding Items}">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Value1}">
            <DataGridTextColumn.HeaderTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding DataContext.ColumnTitel1, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
                </DataTemplate>
            </DataGridTextColumn.HeaderTemplate>
        </DataGridTextColumn>
    </DataGrid.Columns>
</DataGrid>

Такая же привязка внутри Header собственность не сложилась.

Мое решение позволяет написать одну строку в DataGridColumn с названием свойства, которое необходимо связать. У него есть следующие особенности:

  • Есть поддержка DataGridTextColumn
  • Есть поддержка DataGridTemplateColumn
  • Задавать StringFormat для каждого столбца
  • Укажите статическое значение для StringFormat
  • Полностью соответствует шаблону MVVM

Пример, который приведен ниже, включает в себя StringFormat (он должен стоять перед PropertyPath):

<DataGridTextColumn Behaviors:DataGridHeader.StringFormat="StringFormat: {0:C}"
                    Behaviors:DataGridHeader.PropertyPath="HeaderValueOne" ... /> 

Эквивалент этой линии:

<DataGridTextColumn HeaderStringFormat="{0:C}"
                    Header="{Binding Path=HeaderValueOne}" ... />

Кому нужно больше примеров решений и функций, читайте ниже.

Link для примера проекта.


Notes about the solution

Из всех решений, которые я видел ранее, самым простым для меня оказалось это example:

<DataGridTextColumn Binding="{Binding Name}">
    <DataGridTextColumn.HeaderTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=DataContext.YourPropertyName,
                                      RelativeSource={RelativeSource AncestorType={x:Type SomeControl}}" />
         </DataTemplate>
    </DataGridTextColumn.HeaderTemplate>
</DataGridTextColumn>        

Пожалуйста, обратите внимание на DataGridTextColumn.HeaderTemplate, если был использован DataGridTextColumn.Header тогда для платформы.NET ниже версии 4.5 и для Silverlight возникнет исключение:

Свойство Header не поддерживает UIElements

Казалось бы, что нужно? Я хотел найти решение, которое позволило бы написать одну строку в DataGridColumn с названием свойства, которое необходимо связать.

И вот что случилось:

<DataGridTextColumn Behaviors:DataGridHeader.PropertyPath="HeaderValueOne" // Attached dependency property 

Эта конструкция похожа на эту:

<DataGridTextColumn Header="{Binding Path=HeaderValueOne}" ... />

Также можно использовать StringFormat для каждого столбца вот так:

<DataGridTextColumn Behaviors:DataGridHeader.StringFormat="StringFormat: {0:C}"
                    Behaviors:DataGridHeader.PropertyPath="TestStringFormatValue" ... />

И есть возможность указать статическое значение для StringFormat:

<DataGridTextColumn Behaviors:DataGridHeader.StringFormat="{x:Static Member=this:TestData.TestStaticStringFormatValue}" // public static string TestStaticStringFormatValue = "Static StringFormat: {0}$";
                    Behaviors:DataGridHeader.PropertyPath="TestStringFormatValue"

Вот оригинал DataTemplate, который динамически устанавливается в столбце:

<DataTemplate>
    <TextBlock Text="{Binding Path=DataContext.YourPropertyName,
                              StringFormat="YourStringFormat",
                              RelativeSource={RelativeSource AncestorType={x:Type DataGridCellsPanel}}}" />
</DataTemplate>

Чтобы RelativeSource не зависит от типа DataContext Я взял отлично solution от г-на Bruno,

В этом случае, DataGridCellsPanel содержит правильный DataContext, который установлен для родительского DataGrid.

Ниже приведен базовый код, в котором выполняется вся магия:

IsSetHeader PropertyChanged handler

private static void IsSetHeader(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
    var textColumn = sender as DataGridTextColumn;
    var templateColumn = sender as DataGridTemplateColumn;
    string path = e.NewValue as string;

    if ((textColumn == null) & (templateColumn == null)) 
    {
        return;
    }

    if (String.IsNullOrEmpty(path) == false)
    {
        currentStringFormat = ReturnStringFormat(textColumn, templateColumn);
        dataTemplate = CreateDynamicDataTemplate(path, currentStringFormat);

        if (dataTemplate != null)
        {
            if (textColumn != null)
                textColumn.HeaderTemplate = dataTemplate;

            if (templateColumn != null)
                templateColumn.HeaderTemplate = dataTemplate;
        }
    }
}

CreateDynamicDataTemplate

private static DataTemplate CreateDynamicDataTemplate(string propertyPath, string stringFormat)
{
    var pc = new ParserContext();
    MemoryStream sr = null;

    string xaml = GetXamlString(propertyPath, stringFormat);            
    sr = new MemoryStream(Encoding.ASCII.GetBytes(xaml));

    pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
    pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");

    return XamlReader.Load(sr, pc) as DataTemplate;
}

GetXamlString

private static string GetXamlString(string propertyPath, string stringFormat)
{
    #region Original PropertyPath for TextBlock

    // {Binding Path=DataContext.YourProperty, RelativeSource={RelativeSource AncestorType={x:Type DataGridCellsPanel}}}"
    // Thanks to Bruno (https://stackru.com/users/248118/bruno) for this trick

    #endregion

    var sb = new StringBuilder();

    sb.Append("<DataTemplate><TextBlock Text=\"{Binding Path=DataContext.");
    sb.Append(propertyPath);
    sb.Append(", StringFormat=");
    sb.Append(stringFormat);
    sb.Append(", RelativeSource={RelativeSource AncestorType={x:Type DataGridCellsPanel}}}\" /></DataTemplate>");

    return sb.ToString();
}

StringFormat должен появиться перед PropertyPath, потому что это необязательно. Для того, чтобы для столбцов, у которых его не было, не возникает исключение, я зарегистрировал try-catch в GetStringFormat:

 public static string GetStringFormat(DependencyObject DepObject)
 {
    try
    {
        return (string)DepObject.GetValue(StringFormatProperty);
    }

    catch 
    {
        return String.Empty;
    }
 }

Плюс: не пишите в блоке try-catch методы, которые пытаются получить значение.

Минус: минус за каждый пропущенный StringFormat исключение будет сгенерировано один раз при запуске программы. Если это важно для вас, вы всегда можете указать StringFormat="null" для столбца.

На всякий случай покажите полный код проекта:

public static class DataGridHeader
{
    #region Private Section

    private static string textColumnStringFormat = null;
    private static string templateColumnStringFormat = null;
    private static string currentStringFormat = null;
    private static DataTemplate dataTemplate = null;

    #endregion

    #region PropertyPath DependencyProperty

    public static readonly DependencyProperty PropertyPathProperty;

    public static void SetPropertyPath(DependencyObject DepObject, string value)
    {
        DepObject.SetValue(PropertyPathProperty, value);
    }

    public static string GetPropertyPath(DependencyObject DepObject)
    {
        return (string)DepObject.GetValue(PropertyPathProperty);
    }

    #endregion

    #region StringFormat DependencyProperty

    public static readonly DependencyProperty StringFormatProperty;

    public static void SetStringFormat(DependencyObject DepObject, string value)
    {
        DepObject.SetValue(StringFormatProperty, value);
    }

    public static string GetStringFormat(DependencyObject DepObject)
    {
        try
        {
            return (string)DepObject.GetValue(StringFormatProperty);
        }

        catch 
        {
            return String.Empty;
        }
    }

    #endregion

    #region Constructor

    static DataGridHeader()
    {
        PropertyPathProperty = DependencyProperty.RegisterAttached("PropertyPath",
                                                                   typeof(string),
                                                                   typeof(DataGridHeader),
                                                                   new UIPropertyMetadata(String.Empty, IsSetHeader));

        StringFormatProperty = DependencyProperty.RegisterAttached("StringFormat",
                                                                   typeof(string),
                                                                   typeof(DataGridHeader),
                                                                   new UIPropertyMetadata(String.Empty));  
    }

    #endregion

    #region IsSetHeader PropertyChanged Handler

    private static void IsSetHeader(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        var textColumn = sender as DataGridTextColumn;
        var templateColumn = sender as DataGridTemplateColumn;
        string path = e.NewValue as string;

        if ((textColumn == null) & (templateColumn == null)) 
        {
            return;
        }

        if (String.IsNullOrEmpty(path) == false)
        {
            currentStringFormat = ReturnStringFormat(textColumn, templateColumn);
            dataTemplate = CreateDynamicDataTemplate(path, currentStringFormat);

            if (dataTemplate != null)
            {
                if (textColumn != null)
                    textColumn.HeaderTemplate = dataTemplate;

                if (templateColumn != null)
                    templateColumn.HeaderTemplate = dataTemplate;
            }
        }
    }

    #endregion

    #region ReturnStringFormat Helper

    private static string ReturnStringFormat(DependencyObject depObject1, DependencyObject depObject2) 
    {
        textColumnStringFormat = GetStringFormat(depObject1) as string;
        templateColumnStringFormat = GetStringFormat(depObject2) as string;

        if (String.IsNullOrEmpty(textColumnStringFormat) == false)
        {
            return textColumnStringFormat;
        }

        if (String.IsNullOrEmpty(templateColumnStringFormat) == false)
        {
            return templateColumnStringFormat;
        }

        return "null";
    }

    #endregion

    #region CreateDynamicDataTemplate Helper

    private static DataTemplate CreateDynamicDataTemplate(string propertyPath, string stringFormat)
    {
        var pc = new ParserContext();
        MemoryStream sr = null;

        string xaml = GetXamlString(propertyPath, stringFormat);            
        sr = new MemoryStream(Encoding.ASCII.GetBytes(xaml));

        pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
        pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");

        return XamlReader.Load(sr, pc) as DataTemplate;
    }

    #endregion

    #region GetXamlString Helper

    private static string GetXamlString(string propertyPath, string stringFormat)
    {
        #region Original PropertyPath for TextBlock

        // {Binding Path=DataContext.YourProperty, RelativeSource={RelativeSource AncestorType={x:Type DataGridCellsPanel}}}"
        // Thanks to Bruno (https://stackru.com/users/248118/bruno) for this trick

        #endregion

        var sb = new StringBuilder();

        sb.Append("<DataTemplate><TextBlock Text=\"{Binding Path=DataContext.");
        sb.Append(propertyPath);
        sb.Append(", StringFormat=");
        sb.Append(stringFormat);
        sb.Append(", RelativeSource={RelativeSource AncestorType={x:Type DataGridCellsPanel}}}\" /></DataTemplate>");

        return sb.ToString();
    }

    #endregion
}

XAML

<Window x:Class="BindingHeaderInDataGrid.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:this="clr-namespace:BindingHeaderInDataGrid"
        xmlns:Behaviors="clr-namespace:BindingHeaderInDataGrid.AttachedBehaviors"
        WindowStartupLocation="CenterScreen"
        Title="MainWindow" Height="220" Width="600">

    <Window.DataContext>
        <this:TestData />
    </Window.DataContext>

    <Grid Name="TestGrid">
        <DataGrid Name="TestDataGrid" 
                  Width="550"
                  Height="100"
                  Margin="10"
                  VerticalAlignment="Top"
                  Background="AliceBlue">

            <DataGrid.Columns>
                <DataGridTextColumn Behaviors:DataGridHeader.StringFormat="StringFormat: {0:C}"
                                    Behaviors:DataGridHeader.PropertyPath="TestStringFormatValue"
                                    Width="100"
                                    IsReadOnly="False">

                    <DataGridTextColumn.HeaderStyle>
                        <Style TargetType="{x:Type DataGridColumnHeader}">
                            <Setter Property="Height" Value="20" />
                            <Setter Property="Background" Value="Pink" />
                            <Setter Property="Margin" Value="2,0,0,0" />
                        </Style>
                    </DataGridTextColumn.HeaderStyle>
                </DataGridTextColumn>

                <DataGridTextColumn Behaviors:DataGridHeader.StringFormat="{x:Static Member=this:TestData.TestStaticStringFormatValue}"
                                    Behaviors:DataGridHeader.PropertyPath="TestStringFormatValue"
                                    Width="2*"
                                    IsReadOnly="False">

                    <DataGridTextColumn.HeaderStyle>
                        <Style TargetType="{x:Type DataGridColumnHeader}">
                            <Setter Property="Height" Value="20" />
                            <Setter Property="Background" Value="CadetBlue" />
                            <Setter Property="Margin" Value="2,0,0,0" />
                        </Style>
                    </DataGridTextColumn.HeaderStyle>
                </DataGridTextColumn>

                <DataGridTextColumn Behaviors:DataGridHeader.PropertyPath="TestUsualHeaderValue"
                                    Width="1.5*" 
                                    IsReadOnly="False">

                    <DataGridTextColumn.HeaderStyle>
                        <Style TargetType="{x:Type DataGridColumnHeader}">
                            <Setter Property="Height" Value="20" />
                            <Setter Property="Background" Value="Gainsboro" />
                            <Setter Property="Margin" Value="2,0,0,0" />
                        </Style>
                    </DataGridTextColumn.HeaderStyle>
                </DataGridTextColumn>

                <DataGridTemplateColumn Behaviors:DataGridHeader.PropertyPath="TestTemplateColumnValue"
                                        Width="150"
                                        IsReadOnly="False">

                    <DataGridTemplateColumn.HeaderStyle>
                        <Style TargetType="{x:Type DataGridColumnHeader}">
                            <Setter Property="Height" Value="20" />
                            <Setter Property="Background" Value="Beige" />
                            <Setter Property="Margin" Value="2,0,0,0" />
                        </Style>
                    </DataGridTemplateColumn.HeaderStyle>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>

        <Button Name="ChangeHeader" 
                Width="100" 
                Height="30"
                VerticalAlignment="Bottom"
                Content="ChangeHeader" 
                Click="ChangeHeader_Click" />
    </Grid>
</Window>

Code-behind

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }        

    private void ChangeHeader_Click(object sender, RoutedEventArgs e)
    {
        TestData data = this.DataContext as TestData;

        data.TestStringFormatValue = "777";
        data.TestUsualHeaderValue = "DynamicUsualHeader";
        data.TestTemplateColumnValue = "DynamicTemplateColumn";
    }
}

public class TestData : NotificationObject
{
    #region TestStringFormatValue

    private string _testStringFormatValue = "1";

    public string TestStringFormatValue
    {
        get
        {
            return _testStringFormatValue;
        }

        set
        {
            _testStringFormatValue = value;
            NotifyPropertyChanged("TestStringFormatValue");
        }
    }

    #endregion

    #region TestStaticStringFormatValue

    public static string TestStaticStringFormatValue = "Static StringFormat: {0}$";

    #endregion

    #region TestUsualHeaderValue

    private string _testUsualHeaderValue = "UsualHeader";

    public string TestUsualHeaderValue
    {
        get
        {
            return _testUsualHeaderValue;
        }

        set
        {
            _testUsualHeaderValue = value;
            NotifyPropertyChanged("TestUsualHeaderValue");
        }
    }

    #endregion

    #region TestTemplateColumnValue

    private string _testTemplateColumnValue = "TemplateColumn";

    public string TestTemplateColumnValue
    {
        get
        {
            return _testTemplateColumnValue;
        }

        set
        {
            _testTemplateColumnValue = value;
            NotifyPropertyChanged("TestTemplateColumnValue");
        }
    }

    #endregion
}

Кстати, в Silverlight (протестировано с SL 3.0) вы можете просто использовать свойство Header в качестве DataContext для ControlTemplate, установленного через HeaderStyle (см. Мой связанный вопрос по SO).

Я только что попробовал это решение в WPF 3.5, используя WPF Toolkit DataGrid, и оно работает!

Еще лучшим решением было бы установить привязку в стиле заголовка и передать столбец как dataContext заголовка... (или даже лучше: установить объект, представляющий dataContext заголовка и передать его)

посмотрите там, как это сделать:

Как установить DataContext в заголовке столбца DataGrid

**РЕДАКТИРОВАТЬ:-

Вы можете стилизовать DataGridColumnHeader и сделать несколько прикольных привязок. попробуйте здесь и скачайте ColumnHeaderBindings.zip, у него есть небольшой тестовый проект, что-то вроде хака, но он работает

** Конец редактирования

Привязка к столбцу происходит отдельно для каждой строки, столбец не является частью визуального дерева, привязка применяется к каждому элементу сетки, из исходного кода сетки вы можете видеть, что свойство Binding имеет эти комментарии

    /// <summary>
    ///     The binding that will be applied to the generated element.
    /// </summary>
    /// <remarks>
    ///     This isn't a DP because if it were getting the value would evaluate the binding.
    /// </remarks>

Поэтому привязка к столбцам не имеет особого смысла, поскольку, как вы выяснили, когда вы не являетесь частью визуального дерева, у вас нет контекста данных.

Та же проблема существует с ComboBoxColumn, когда вы хотите привязать к источнику элементов. Вы можете привязать к StaticResource, но StaticResources также не имеет контекста данных. Вы можете использовать объектный поставщик данных или просто создать экземпляр непосредственно в xaml.

но я бы просто создал столбцы в коде и установил заголовок. эта проблема просто исчезнет тогда.

Здесь есть хорошая статья о визуальном оформлении.

Ответ @mmichtch хорошо работает для меня, вам просто нужно создать локальное пространство имен (xmlns), которое содержит ссылку на ваш проект следующим образом:

xmlns:local="clr-namespace:your_project_name"

и наряду с этим не забудьте упомянуть свойство, которое вы хотите связать:

                <DataGridTextColumn Width="Auto">
                <DataGridTextColumn.Header>
                    <TextBlock Text="{Binding DataContext.PropertyNameYouWantToBind, 
                                          RelativeSource={RelativeSource AncestorType={x:Type local:MainWindow}}}"/>
                </DataGridTextColumn.Header>
            </DataGridTextColumn>

это хорошо работает с VS 2010 и.net версии 4.

Я использовал его для заполнения заголовка столбца DataGrid.

Трюк в режиме привязки. Его "Режим" должен быть установлен на "OneWay". В противном случае это не хорошо.

Пример:

<DataGridTextColumn Binding="{Binding RowData}" Header="{Binding Mode=OneWay, Source={StaticResource spy},Path=DataContext.HeaderText,  FallbackValue= header text}"/>

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

Другие вопросы по тегам