0

私の目標は、WPF データグリッド列にインプレース エディターを作成して、大きなテキストを編集することです。

私のデータソースは、さまざまなテーブルやフィールドからのデータを含めることができる DataTable です。そのため、バインドする定義済みの型がありません。私の例では、「Test」という名前の列が 1 つあります。ここで、列を定義する XAML コードをいくつか書きました。

<ControlTemplate x:Key="ExtendedTemplate">
    <StackPanel>
        <TextBox Text="{Binding Test}" Width="200" Height="100" AcceptsReturn="True" TextWrapping="Wrap"/>
    </StackPanel>
</ControlTemplate>                

<DataGrid x:Name="grid" ItemsSource="{Binding}" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="TEST Column" Width="200">
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <ComboBox IsDropDownOpen="True">
                        <ComboBoxItem Template="{StaticResource ExtendedTemplate}"/>
                    </ComboBox>
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Test}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

ここに私のテストデータソースがあります:

Source = new DataTable("Test");
Source.Columns.Add("Test");
Source.Rows.Add("Item 1 - large amount of text ...");
Source.Rows.Add("Item 2");
Source.Rows.Add("Item 3");
grid.DataContext = Source;

これは問題なく動作しますが、最後に行う必要があるのは、グリッド セルが編集モードで拡張コンボにテキストを入力しているときにグリッド セルを装飾することです。

スクリーンショット

重要: まず、コンボボックスはどの ItemsSource にもバインドされていませんが、単一の ComboBoxItem が任意のセルに存在し、そのセルのテキストが含まれています。

2 番目 - ComboBox.SelectionBoxItemTemplate プロパティが読み取り専用であるため、DataTemplate を SelectedItem に定義できません。

SelectionBoxItem の datatemplate をこのようなものに置き換える方法を知っている人はいますか?

<DataTemplate>
    <TextBlock Text="{Binding Test}"/>
</DataTemplate>

コマンド「テンプレートの編集-コピーの編集...」でコンボボックスのカスタムスタイルを作成しようとしました。多くのマークアップがあり、ここに投稿したくありません。ここに私が編集した小さな部分があります。

<ContentPresenter ContentTemplate="{StaticResource SimplestTemplate}" 
                  ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" 
                  Content="{TemplateBinding SelectionBoxItem}" 
                  ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}"
                  IsHitTestVisible="false"
                  SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                  VerticalAlignment="Stretch"
                  HorizontalAlignment="Stretch"/>

データを「テスト」フィールドにバインドする必要がある「SimplestTemplate」の記述方法がわからないため、機能しません。

4

1 に答える 1

0

から派生したスタイルを作成し、ComboBoxその をオーバーライドすることで、目標を達成しましたContentPresenter ContentTemplate。それは問題なく動作しますが、実装する必要がある多くの追加機能があるため、作業を中止しました (ポップアップ エディターのサイズ変更、グリッド セルの自動更新、キーボードのみでエディターを操作するためのコマンドのホットキーへの割り当てなど)。 . 最後に、サードパーティのコンポーネント ( this one ) を使用することにしました。

私の質問への回答として、最終的な XAML マークアップを投稿します。

資力:

<Window.Resources>

    <DataTemplate x:Key="SimplestTemplate">
        <Grid>
            <TextBlock Background="White" Foreground="Black" Text="{TemplateBinding Content}"/>
        </Grid>
    </DataTemplate>

    <ControlTemplate x:Key="ExtendedTemplate">
        <StackPanel>
            <TextBox Text="{Binding Test}" MinHeight="100" Height="Auto" MinWidth="{TemplateBinding Width}" Width="{Binding MinWidth}" TextWrapping="Wrap"/>
        </StackPanel>
    </ControlTemplate>                

    <Style x:Key="MyComboBoxStyle" TargetType="{x:Type ComboBox}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ComboBox}">
                    <Grid x:Name="MainGrid" SnapsToDevicePixels="true">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" Width="0"/>
                        </Grid.ColumnDefinitions>
                        <Popup x:Name="PART_Popup" AllowsTransparency="true" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" Margin="1" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
                            <Themes:SystemDropShadowChrome x:Name="Shdw" Color="Transparent" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=MainGrid}">
                                <Border x:Name="DropDownBorder" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}">
                                    <ScrollViewer x:Name="DropDownScrollViewer">
                                        <Grid RenderOptions.ClearTypeHint="Enabled">
                                            <Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
                                                <Rectangle x:Name="OpaqueRect" Fill="{Binding Background, ElementName=DropDownBorder}" Height="{Binding ActualHeight, ElementName=DropDownBorder}" Width="{Binding ActualWidth, ElementName=DropDownBorder}"/>
                                            </Canvas>
                                            <ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                        </Grid>
                                    </ScrollViewer>
                                </Border>
                            </Themes:SystemDropShadowChrome>
                        </Popup>
                        <ContentPresenter ContentTemplate="{StaticResource SimplestTemplate}"
                                          ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" 
                                          Content="{TemplateBinding help:ComboboxHelper.BindedText}" 
                                          ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}"                                               
                                          IsHitTestVisible="false"
                                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                          VerticalAlignment="Stretch"
                                          HorizontalAlignment="Stretch"
                                          Grid.ColumnSpan="2"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>      
</Window.Resources>

グリッド列テンプレート:

<DataGridTemplateColumn Header="TEST Column" Width="200">
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <ComboBox IsDropDownOpen="True" Style="{StaticResource MyComboBoxStyle}" FocusVisualStyle="{x:Null}" help:ComboboxHelper.BindedText="{Binding Test}">
                <ComboBoxItem Template="{StaticResource ExtendedTemplate}"/>
            </ComboBox>
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Test}" TextTrimming="CharacterEllipsis"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

クリップされたテキストをセルに表示するために、単純な添付プロパティを作成しました。"\n"テキスト内のすべての記号をカットして、1 行にします。

public static class ComboboxHelper
{
    public static readonly DependencyProperty BindedTextProperty = DependencyProperty.RegisterAttached("BindedText", typeof(string), typeof(ComboboxHelper));

    public static string GetBindedText(DependencyObject obj)
    {
        string s = (string)obj.GetValue(BindedTextProperty);
        s = s.Replace(Environment.NewLine, " ");
        return s;
    }

    public static void SetBindedText(DependencyObject obj, string value)
    {
        obj.SetValue(BindedTextProperty, value);
    }
}
于 2013-01-27T17:50:42.287 に答える