Как изменить фон элементов списка (Textblock) в UWP - PullRequest
1 голос
/ 26 июня 2019

При попытке изменить фон TextBlock, который является частью DataTemplate объекта ListBox, фон только вокруг текста, а не весь блок

В 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, чтобы бытьнарисован полностью, а не только вокруг текста

1 Ответ

1 голос
/ 27 июня 2019

По вашему вопросу вам не нужно использовать рамку, чтобы обернуть StackPanel, она не будет работать. Вам просто нужно определить стиль для ListBoxItem и применить его к ItemContainerStyle и установить HorizontalContentAlignment=Stretch.

Здесь я проверил ваш код. У меня есть несколько предложений для вас. В UWP вы могли бы делать большинство вещей с привязкой. Это означает, что вам не нужно находить конкретный элемент управления и устанавливать значение его свойства из DataTemplate в коде страницы. Это не лучшая практика. Вместо этого вы можете определить пользовательский класс, который включает три свойства (текст, фон, передний план). Затем вы можете связать эти свойства со своей страницей 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) });
        }
    }
}
...