WPF DataGridColumnHeader模板中

时间:2016-11-30 09:57:35

标签: c# wpf xaml wpfdatagrid xaml-binding

我的目标是将类似“A__B”的格式字符串传递给DataGrid列的标题并将其显示为 A带有下标B(即A_B)。为了按列进行此操作,我打算使用此模板,如下所示。

<DataGridTextColumn Binding="{Binding AB}", Header="A__B" HeaderStyle="{StaticResource ColumnHeaderTemplate}" />            

为了完成合适模板的实现,我想我可能想要使用转换器。因此,我写道 一个简单的转换器,它将字符串拆分为Symbol类的对象,具有Text和Subscript属性。

using System;
using System.Windows.Data;
using System.Globalization;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace Test
{
    public class Symbol : INotifyPropertyChanged
    {
        string text_, subscript_;

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        public Symbol(string text, string subscript)
        {
            Text = text;
            Subscript = subscript;

            NotifyPropertyChanged();
        }

        public String Text
        {
            get { return text_; }
            set { text_ = value; NotifyPropertyChanged(); }
        }

        public String Subscript
        {
            get { return subscript_; }
            set { subscript_ = value; NotifyPropertyChanged(); }
        }
    }

    [ValueConversion(typeof(string), typeof(Symbol))]
    public class StringToSymbolConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (parameter == null) return null;

            var format = parameter as string;

            int idx = format.IndexOf("__");
            if (idx < 0) return new Symbol(format, "");

            return new Symbol(format.Substring(0, idx), format.Substring(idx + 2);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }
    }
}

我将此转换器添加到窗口资源

<Window.Resources>
    <l:StringToSymbolConverter x:Key="stringToSymbolConverter" />
</Window.Resources>

在我的数据网格中,我做了以下

    <DataGrid x:Name="dataGrid" ItemsSource="{Binding Results}" AutoGenerateColumns="False">

        <DataGrid.Resources>
            <Style TargetType="{x:Type DataGridColumnHeader}" x:Key="ColumnHeaderTemplate">
                <Setter Property="ContentTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <TextBlock TextWrapping="Wrap" DataContext="{Binding Converter={StaticResource stringToSymbolConverter}}">
                                <Run Text="{Binding Path=Text}"/>
                                <Run Text="{Binding Path=Subscript}" BaselineAlignment="Subscript" FontSize="8"/>
                            </TextBlock>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </DataGrid.Resources>

        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding AB, Mode=OneWay}" ClipboardContentBinding="{x:Null}" Header="A__B" HeaderStyle="{StaticResource ColumnHeaderTemplate}" />         
        </DataGrid.Columns>
    </DataGrid>

我的想法是进行一次转换 然后将驻留在Symbol对象中的组件插入正确的位置。为此我试图(错误?)使用文本块的DataContext。

现在这不能按预期工作,我没有可见的输出。我看到模板正在应用于相应的列,所以我似乎有一个正确的。此外,如果我用纯文本替换绑定或添加回退值,则会正确呈现文本。我怀疑绑定失败并在运行时传递一个空字符串。作为WPF的新手,并且在XAML / WPF中使用相当有限的调试工具链,我很难找出错误的地方以及从何处开始。

我可能已经将绑定游戏中涉及的依赖关系完全错误了,这可能是由于我对底层机制缺乏了解,特别是在涉及模板时。因此,我感谢任何有用的提示!

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

错误在于您的转换器 - 也就是说,您尝试转换参数sudo easy_install pip Traceback (most recent call last): File "/usr/local/bin/easy_install", line 11, in <module> load_entry_point('setuptools==29.0.1', 'console_scripts', 'easy_install')() File"/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/pkg_resources/__init__.py", line 565, in load_entry_point return get_distribution(dist).load_entry_point(group, name) File"/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/pkg_resources/__init__.py", line 2697, in load_entry_point return ep.load() File"/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/pkg_resources/__init__.py", line 2370, in load return self.resolve() File"/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/pkg_resources/__init__.py", line 2376, in resolve module = __import__(self.module_name, fromlist=['__name__'], level=0) File "build/bdist.macosx-10.12-intel/egg/setuptools/__init__.py", line 10, in <module> File "build/bdist.macosx-10.12 intel/egg/setuptools/extern/__init__.py", line 1, in <module> ImportError: No module named extern 而不是值,因为您没有为null指定ConverterParameter使用转换器的绑定。因此,您将获得一个空列标题。您应该转换该值:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    //here you should use 'value' instead of 'parameter'
    if (value == null) return null;
    var format = value as string;

    int idx = format.IndexOf("__");
    if (idx < 0) return new Symbol(format, "");

    return new Symbol(format.Substring(0, idx), format.Substring(idx + 2);
}

请注意,这种错误很容易调试 - 当您遇到涉及转换器的绑定问题时,在Convert方法中设置断点并逐步执行它是有益的。 / p>