1

プロジェクトでは、コントロールのような小さなIntelliSenseを実装しました。これは。にすぎませんListBox。それDataTemplateは1つと1つをStackPanel保持することで構成されています。他には何もありません。私のコントロールの最初のスクリーンショットでわかるように、ListBoxの選択ボックスはアイテム全体を選択します(これは通常、まさに期待どおりです)。ImageTextBlock

カスタムリストボックス

ただし、VS11から「盗まれた」アイコンは低品質であるため、VisualStudioのように選択を調整したいと思いました。

Visual Studio IntelliSense

テキストのみが選択されていることがわかり(視覚的表現は画像/アイコンを無視します)、この動作を実装する方法も知りたいです。

編集:アイコンは、背景が透明なGIFファイルです。私はそれらをより良いものと交換しますが、それでも私は望ましい振る舞いを得る方法に興味があります。

4

2 に答える 2

3

ListBoxItem コントロール テンプレートを置き換えることによる解決策を次に示します。私のテストでは、2 つのテキスト文字列を表示し、2 番目の文字列を強調表示しました。

<Page.Resources>
    <Style x:Key="ItemStyle" TargetType="ListBoxItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <ContentPresenter/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <Style x:Key="Selected" TargetType="{x:Type TextBlock}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=IsSelected, 
                         RelativeSource={RelativeSource Mode=FindAncestor, 
                         AncestorType={x:Type ListBoxItem}}}" Value="True">
                <Setter Property="Background" 
                        Value="{x:Static SystemColors.HighlightBrush}"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>

    <DataTemplate x:Key="ItemTemplate" DataType="{x:Type ViewModel:DataItem}">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="auto" SharedSizeGroup="c1"/>
                <ColumnDefinition Width="auto" SharedSizeGroup="c2"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Image Source="../Images/Collapse.png"/>
            <TextBlock Grid.Column="1" Text="{Binding Name}" Margin="0,0,5,0"/>
            <TextBlock Style="{StaticResource Selected}" 
                       Grid.Column="2" Text="{Binding Description}"/>
        </Grid>
    </DataTemplate>
</Page.Resources>

<Page.DataContext>
    <Samples:Page3ViewModel/>
</Page.DataContext>

<Grid>
    <ListBox 
        Grid.IsSharedSizeScope="True"
        SelectedIndex="2"
        HorizontalContentAlignment="Stretch"
        ItemsSource="{Binding Items}" 
        ItemContainerStyle="{StaticResource ItemStyle}"
        ItemTemplate="{StaticResource ItemTemplate}"/>
</Grid>

ビュー モデルには、単純なデータ項目のコレクションが含まれています

public class Page3ViewModel
{
    public Page3ViewModel()
    {
        Items = new List<DataItem>
            {
                new DataItem{Name = "One", Description = "First"},
                new DataItem{Name = "Two", Description = "Second"},
                new DataItem{Name = "Three", Description = "Third"},
                new DataItem{Name = "Four", Description = "Fourth"},
            };
    }
    public IEnumerable<DataItem> Items { get; private set; }
}

与える

ここに画像の説明を入力

于 2012-06-16T15:57:33.550 に答える
1

あなたの問題は、WPF がListBoxの各項目をレンダリングする方法が原因です。各項目をListBoxItemにラップするItemContainerStyleを使用します。表示されるコンテンツを含むのはこのListBoxItemです (この場合、Image と TextBlock を含む StackPanel)。

デフォルトでは、ListBoxItemは、表示するすべてのコンテンツを囲む青い四角形を表示します。

私は解決策を思いつきましたが、それはハックです。画像を大きくし、背景のピクセルの色をリストボックスの背景色(私の場合は白) と一致させ、次の XAML を使用するだけです。

<ListBox Margin="5"
         ItemsSource="{Binding Items}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal"
                        Margin="-2,0,0,0">
                <Image Source="Save-icon.png" />
                <TextBlock Margin="5,8,0,0"
                           Text="{Binding}" />
            </StackPanel>
        </DataTemplate>
     </ListBox.ItemTemplate>
</ListBox>

結果は次のとおりです。

ここに画像の説明を入力

アップデート

私はこれをハックの少し少なくする修正を思いついた. 私のItemTemplateでは、バインディングを使用して親のListBoxから背景色を取得するBorderで画像を囲みました。(画像の周囲に境界線がなくなりました)。

XAML を次のように更新します。

<ListBox Margin="5"
         ItemsSource="{Binding Items}"
         Background="LightSteelBlue">

    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal"
                        Margin="-2,0,0,0">
                <Border Background="{Binding Path=Background, RelativeSource={RelativeSource AncestorType=ListBox}}"
                        Padding="10">
                    <Image Source="Save-icon.png"/>
                 </Border>
                 <TextBlock Margin="5,8,0,0"
                            Text="{Binding}" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>

</ListBox>

これは新しい結果です:

ここに画像の説明を入力

あとは、 ListBoxの背景色を更新するだけで、すべてが自動的に調整されます。例えば

<ListBox Margin="20"
         ItemsSource="{Binding Items}"
         Background="PeachPuff">

ここに画像の説明を入力

于 2012-06-16T14:58:26.167 に答える