0

私の目標は、"A__B" のような書式文字列を DataGrid 列のヘッダーに渡し、それを下付き文字 B を付けた A (つまりA_B) として表示することです。列ごとにこれを行うには、次のようにテンプレートを使用するつもりです。

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

適切なテンプレートを実装するには、コンバーターを使用する必要があると考えました。したがって、文字列を Text および Subscript プロパティを持つ Symbol クラスのオブジェクトに分割する単純なコンバーターを作成しました。

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 のデバッグ ツールチェーンがかなり限られているため、何が問題でどこに行くべきかを見つけるのは非常に困難です。

バインディング ゲームに関係する依存関係が完全に間違っている可能性があります。これは、特にテンプレートに関して、基礎となるメカニズムを理解していないことが原因である可能性があります。したがって、役立つヒントに感謝します!

何か案は?

4

1 に答える 1

1

エラーはコンバーターにあります。つまり、値の代わりに、パラメーターを変換しようとしています。これは、コンバーターが使用されているバインディングを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メソッドにブレークポイントを設定してステップ スルーすることをお勧めします。

于 2016-11-30T11:39:27.107 に答える