C# 调整WPF列表框选择框的大小
对于一个项目,我实现了一个类似IntelliSense的控件,它只不过是一个C# 调整WPF列表框选择框的大小,c#,wpf,listbox,styles,datatemplate,C#,Wpf,Listbox,Styles,Datatemplate,对于一个项目,我实现了一个类似IntelliSense的控件,它只不过是一个列表框。它的DataTemplate由一个StackPanel组成,其中包含一个Image和一个TextBlock。没有别的了。正如您在my控件的第一个屏幕截图中所看到的,ListBox的选择框选择整个项目(这通常正是人们所期望的): 但是,我的VS11“被盗”图标质量很低,因此我想像Visual Studio那样调整选择: 您可以看到,只选择了文本(视觉表示确实忽略了图像/图标),我也想知道如何实现此行为 编辑:图
列表框
。它的DataTemplate
由一个StackPanel
组成,其中包含一个Image
和一个TextBlock
。没有别的了。正如您在my控件的第一个屏幕截图中所看到的,ListBox的选择框选择整个项目(这通常正是人们所期望的):
但是,我的VS11“被盗”图标质量很低,因此我想像Visual Studio那样调整选择:
您可以看到,只选择了文本(视觉表示确实忽略了图像/图标),我也想知道如何实现此行为
编辑:图标只是带有透明背景的GIF文件。我会用更好的来替换它们,但是我对如何获得所需的行为感兴趣。您的问题是由于WPF呈现列表框中每个项目的方式。它使用ItemContainerStyle将每个项目包装在ListBoxItem中。此ListBoxItem包含要显示的内容(在您的示例中是包含图像和文本块的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中,我用一个边框包围了图像,该边框使用绑定从其父列表框获取其背景颜色。(图像周围不再有边框)
将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 Margin="20"
ItemsSource="{Binding Items}"
Background="PeachPuff">
您的问题是由于WPF呈现列表框中每个项目的方式造成的。它使用ItemContainerStyle将每个项目包装在ListBoxItem中。此ListBoxItem包含要显示的内容(在您的示例中是包含图像和文本块的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中,我用一个边框包围了图像,该边框使用绑定从其父列表框获取其背景颜色。(图像周围不再有边框)
将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 Margin="20"
ItemsSource="{Binding Items}"
Background="PeachPuff">
这里有一个替换ListBoxItem控件模板的解决方案。在我的测试中,我只显示两个文本字符串,第二个突出显示
<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; }
}
公共类Page3ViewModel
{
公共页面3ViewModel()
{
项目=新列表
{
新数据项{Name=“One”,Description=“First”},
新数据项{Name=“Two”,Description=“Second”},
新数据项{Name=“Three”,Description=“Third”},
新数据项{Name=“Four”,Description=“Fourth”},
};
}
公共IEnumerable项{get;private set;}
}
给予
这里有一个替换ListBoxItem控件模板的解决方案。在我的测试中,我只显示两个文本字符串,第二个突出显示
<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; }
}
公共类Page3ViewModel
{
公共页面3ViewModel()
{
项目=新列表
{
新数据项{Name=“One”,Description=“First”},
新数据项{Name=“Two”,Description=“Second”},
新数据项{Name=“Three”,Description=“Third”},
新数据项{Name=“Four”,Description=“Fourth”},
};
}
公共IEnumerable项{get;private set;}
}
给予
你的图像有透明背景吗?你能改变文本块的背景而不是整个StackPanel吗?@benjer3:我没有改变