如何更改 UWP 中列表框项目(文本块)的背景
How to change background of listbox items (Textblock) in UWP
当尝试更改作为 ListBox 的 DataTemplate 的一部分的 TextBlock 的背景时,背景仅围绕文本而不是整个块
在 UWP 中,TextBlock 没有背景 属性 所以我将它包裹在边框中并更改了边框的背景,如下所示:
<ListBox x:Name="BitsListView" ItemsSource="{x:Bind BitsList, Mode=TwoWay}" Loaded="BitsListView_Loaded"
HorizontalAlignment="Left" IsEnabled="{x:Bind IsWriteAccess,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
SelectionChanged="BitsListView_SelectionChanged " SelectionMode="Single">
<ListBox.ItemTemplate>
<DataTemplate>
<Border>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="BitText" Text="{Binding}" Loaded="BitText_Loaded" />
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
并且颜色在 OnLoaded 事件中更改如下:
private void BitText_Loaded(object sender, RoutedEventArgs e)
{
TextBlock bitText = sender as TextBlock;
StackPanel sp = bitText.Parent as StackPanel;
Border border = sp.Parent as Border;
if ((int)bitText.DataContext == 1)
{
bitText.Foreground = new SolidColorBrush(Windows.UI.Colors.LightGreen);
border.Background = new SolidColorBrush(Windows.UI.Colors.DarkGreen);
}
else
{
bitText.Foreground = new SolidColorBrush(Windows.UI.Colors.Gray);
border.Background = new SolidColorBrush(Windows.UI.Colors.LightGray);
}
}
但结果是这样的:
https://pasteboard.co/IlcZB1J.png
我想要实现的是这样的:
(不要介意糟糕的 MSPaint 作业)
https://pasteboard.co/Ild1plp.png
我试图解决这个问题的方法是用边框包裹堆栈面板,但这没有帮助。
然后我尝试包装数据模板,但这是不可能的,进一步爬上树改变背景无法正常工作,显然改变 ListBox 的背景会绘制整个列表,我只需要有 1 的块画得完整,而不仅仅是文字周围的一点点
对于你的问题,你不需要使用border来包裹StackPanel,这样是行不通的。您只需要为 ListBoxItem
定义一个样式并将其应用于 ItemContainerStyle
并设置 HorizontalContentAlignment=Stretch
.
在这里,我检查了你的代码。我有一些建议给你。在 UWP 中,您可以使用绑定完成大部分操作。这意味着您不需要找到特定控件并从页面 code-behind 中的 DataTemplate 设置其 属性 值。这不是最佳做法。相反,您可以定义一个包含三个属性(文本、背景、前景)的自定义 class。然后,您可以在 XAML 页面上绑定到这些属性。
完整的代码示例如下:
<ListView x:Name="BitsListView" ItemsSource="{x:Bind BitsList, Mode=TwoWay}"
HorizontalAlignment="Left" SelectionMode="Single">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="VerticalContentAlignment" Value="Stretch"></Setter>
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
<Setter Property="Padding" Value="0"></Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" ></StackPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Test">
<StackPanel Background="{x:Bind backGround}">
<TextBlock x:Name="BitText" Text="{x:Bind content}" Foreground="{x:Bind foreGround}" HorizontalTextAlignment="Center"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
public class Test : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private int _content;
public int content
{
get { return _content; }
set
{
if (_content != value)
{
_content = value;
if (value == 1)
{
foreGround = new SolidColorBrush(Colors.LightGreen);
backGround = new SolidColorBrush(Colors.DarkGreen);
}
else
{
foreGround = new SolidColorBrush(Colors.Gray);
backGround = new SolidColorBrush(Colors.LightGray);
}
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("content"));
}
}
}
private SolidColorBrush _backGround;
public SolidColorBrush backGround
{
get { return _backGround; }
set
{
if (_backGround != value)
{
_backGround = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("backGround"));
}
}
}
private SolidColorBrush _foreGround;
public SolidColorBrush foreGround
{
get { return _foreGround; }
set
{
if (_foreGround != value)
{
_foreGround = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("foreGround"));
}
}
}
}
public sealed partial class MainPage : Page
{
private ObservableCollection<Test> BitsList { get; set; }
public MainPage()
{
this.InitializeComponent();
BitsList = new ObservableCollection<Test>();
for (int i = 0; i < 10; i++)
{
Random random = new Random();
BitsList.Add(new Test() { content = random.Next(0, 9) });
}
}
}
当尝试更改作为 ListBox 的 DataTemplate 的一部分的 TextBlock 的背景时,背景仅围绕文本而不是整个块
在 UWP 中,TextBlock 没有背景 属性 所以我将它包裹在边框中并更改了边框的背景,如下所示:
<ListBox x:Name="BitsListView" ItemsSource="{x:Bind BitsList, Mode=TwoWay}" Loaded="BitsListView_Loaded"
HorizontalAlignment="Left" IsEnabled="{x:Bind IsWriteAccess,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
SelectionChanged="BitsListView_SelectionChanged " SelectionMode="Single">
<ListBox.ItemTemplate>
<DataTemplate>
<Border>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="BitText" Text="{Binding}" Loaded="BitText_Loaded" />
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
并且颜色在 OnLoaded 事件中更改如下:
private void BitText_Loaded(object sender, RoutedEventArgs e)
{
TextBlock bitText = sender as TextBlock;
StackPanel sp = bitText.Parent as StackPanel;
Border border = sp.Parent as Border;
if ((int)bitText.DataContext == 1)
{
bitText.Foreground = new SolidColorBrush(Windows.UI.Colors.LightGreen);
border.Background = new SolidColorBrush(Windows.UI.Colors.DarkGreen);
}
else
{
bitText.Foreground = new SolidColorBrush(Windows.UI.Colors.Gray);
border.Background = new SolidColorBrush(Windows.UI.Colors.LightGray);
}
}
但结果是这样的: https://pasteboard.co/IlcZB1J.png
我想要实现的是这样的: (不要介意糟糕的 MSPaint 作业)
https://pasteboard.co/Ild1plp.png
我试图解决这个问题的方法是用边框包裹堆栈面板,但这没有帮助。 然后我尝试包装数据模板,但这是不可能的,进一步爬上树改变背景无法正常工作,显然改变 ListBox 的背景会绘制整个列表,我只需要有 1 的块画得完整,而不仅仅是文字周围的一点点
对于你的问题,你不需要使用border来包裹StackPanel,这样是行不通的。您只需要为 ListBoxItem
定义一个样式并将其应用于 ItemContainerStyle
并设置 HorizontalContentAlignment=Stretch
.
在这里,我检查了你的代码。我有一些建议给你。在 UWP 中,您可以使用绑定完成大部分操作。这意味着您不需要找到特定控件并从页面 code-behind 中的 DataTemplate 设置其 属性 值。这不是最佳做法。相反,您可以定义一个包含三个属性(文本、背景、前景)的自定义 class。然后,您可以在 XAML 页面上绑定到这些属性。
完整的代码示例如下:
<ListView x:Name="BitsListView" ItemsSource="{x:Bind BitsList, Mode=TwoWay}"
HorizontalAlignment="Left" SelectionMode="Single">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="VerticalContentAlignment" Value="Stretch"></Setter>
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
<Setter Property="Padding" Value="0"></Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" ></StackPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Test">
<StackPanel Background="{x:Bind backGround}">
<TextBlock x:Name="BitText" Text="{x:Bind content}" Foreground="{x:Bind foreGround}" HorizontalTextAlignment="Center"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
public class Test : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private int _content;
public int content
{
get { return _content; }
set
{
if (_content != value)
{
_content = value;
if (value == 1)
{
foreGround = new SolidColorBrush(Colors.LightGreen);
backGround = new SolidColorBrush(Colors.DarkGreen);
}
else
{
foreGround = new SolidColorBrush(Colors.Gray);
backGround = new SolidColorBrush(Colors.LightGray);
}
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("content"));
}
}
}
private SolidColorBrush _backGround;
public SolidColorBrush backGround
{
get { return _backGround; }
set
{
if (_backGround != value)
{
_backGround = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("backGround"));
}
}
}
private SolidColorBrush _foreGround;
public SolidColorBrush foreGround
{
get { return _foreGround; }
set
{
if (_foreGround != value)
{
_foreGround = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("foreGround"));
}
}
}
}
public sealed partial class MainPage : Page
{
private ObservableCollection<Test> BitsList { get; set; }
public MainPage()
{
this.InitializeComponent();
BitsList = new ObservableCollection<Test>();
for (int i = 0; i < 10; i++)
{
Random random = new Random();
BitsList.Add(new Test() { content = random.Next(0, 9) });
}
}
}