Гость
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / ListBox - ещё вопрос по фону / 15 сообщений из 15, страница 1 из 1
12.04.2016, 12:42
    #39213495
13th
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListBox - ещё вопрос по фону
Делаю сравнивалку текстовых файлов (наподобии SVN-овского). Сделал 2 ListBox-а, в каждом первая колонка - номер строки, вторая - содержимое. Фон второй колонки строки меняется, в зависимости от содержимого. Первая колонка всегда серая.

Как теперь показать selection? отрисовка выделенной строки всегда оказывается ПОД отрисовкой элементов строки.

Мой код:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
	<Window.Resources>
		<DataTemplate x:Key="listItemTemplate">
			<Grid>
				<Grid.ColumnDefinitions>
					<ColumnDefinition Width="45" />
					<ColumnDefinition Width="*" />
				</Grid.ColumnDefinitions>
				<TextBlock Grid.Column="0" 
						   Text="{Binding LineNumberText}" 
						   HorizontalAlignment="Stretch"
						   TextAlignment="Right"
						   FontFamily="Courier New" FontWeight="DemiBold" 
						   Margin="3,0" 
						   Padding="3"
						   Background="LightGray"
						   Width="Auto"/>
				<TextBlock Grid.Column="1"
						   Text="{Binding Text}" 
						   Background="{Binding Background}" 
						   FontFamily="Courier New" 
						   Margin="2,0" 
						   Padding="3"
						   Width="Auto"/>
			</Grid>
		</DataTemplate>

		<Style x:Key="listItemStyle">
			<Setter Property="Control.Padding" Value="0" />
			<Setter Property="Control.BorderThickness" Value="0" />
		</Style>
	</Window.Resources>


		<ListBox Name="oldItem" HorizontalContentAlignment="Stretch" 
				 ItemTemplate="{StaticResource listItemTemplate}" ItemsSource="{Binding OldText}"
				 ItemContainerStyle="{StaticResource listItemStyle}" />
...
Рейтинг: 0 / 0
12.04.2016, 12:54
    #39213509
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListBox - ещё вопрос по фону
У ListBoxItem есть свойство IsSelected - повесь на него триггер и делай что хочешь.
...
Рейтинг: 0 / 0
12.04.2016, 13:12
    #39213533
13th
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListBox - ещё вопрос по фону
А можно конкретно кусок кода? Попробовал вот так:

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
		<Style x:Key="listItemStyle">
			<Setter Property="Control.Padding" Value="0" />
			<Setter Property="Control.BorderThickness" Value="0" />
			<Style.Triggers>
				<Trigger Property="ListBoxItem.IsSelected" Value="True">
					<Setter Property="ListBoxItem.Background" Value="DarkRed" />
				</Trigger>
			</Style.Triggers>
		</Style>



что-то не работает.
...
Рейтинг: 0 / 0
12.04.2016, 13:20
    #39213537
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListBox - ещё вопрос по фону
Так а что ты хочешь поменять-то?
Ты меняешь ListBoxItem.Background, а тебе надо же менять фон твоего шаблона, правильно я понял?
...
Рейтинг: 0 / 0
12.04.2016, 13:38
    #39213577
13th
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListBox - ещё вопрос по фону
Вот так хочу:
...
Рейтинг: 0 / 0
12.04.2016, 13:41
    #39213580
13th
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListBox - ещё вопрос по фону
Вообще, сделать это можно несколькими способами. Может, делать bg у элемента итема не правильно? Может, надо сделать какой-нибудь Converter, он будет конвертировать данные в цвет фона всего итема, тогда не надо будет расскрашивать текст. Если я правильно понял, если я сейчас сделаю замену фона, у меня selection всё равно будет "проваливаться" под второй TextBlock, у которого устанавливается свой bg.
...
Рейтинг: 0 / 0
12.04.2016, 13:49
    #39213595
13th
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListBox - ещё вопрос по фону
Вот кстати, так и сделал, курсор перестал проваливаться, но он, почему-то всё равно не тёмно-красный.

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
		<Style x:Key="listItemStyle">
			<Setter Property="Control.Padding" Value="0" />
			<Setter Property="Control.BorderThickness" Value="0" />
			<Setter Property="Control.Background" Value="{Binding Background}" />
			<Style.Triggers>
				<Trigger Property="ListBoxItem.IsSelected" Value="True">
					<Setter Property="ListBoxItem.Background" Value="DarkRed" />
				</Trigger>
			</Style.Triggers>
		</Style>
...
Рейтинг: 0 / 0
12.04.2016, 14:15
    #39213647
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListBox - ещё вопрос по фону
2 пути:
А) переопределить системный ресурс кисти для выделенных элементов в области ListBox
Б) переопределить шаблон ListBoxItem и задать свой триггер на IsSelect
...
Рейтинг: 0 / 0
12.04.2016, 14:24
    #39213657
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListBox - ещё вопрос по фону
13th, можно просто сделать прозрачным цвет фона для шаблона выделенного элемента. А можно конкретным. При этом можно сделать это триггером прямо внутри шаблона, зацепив IsSelected через RelativeSource.

Путей действительно много.
...
Рейтинг: 0 / 0
12.04.2016, 15:08
    #39213721
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListBox - ещё вопрос по фону
Shocker.Pro,

этот путь неверный, нужно чётко отделять ControlTemplate'ы от DataTemplate'ов.
Считаю, что DataTemplate не должен через поиск в визуальном дереве обращаться к свойствам шаблона элемента управления.
DataTemplate должен визуализировать данные, модель представления, что угодно, но он не должен быть привязан к элементам управления.
Вся суть в WPF и шаблона в абстракции, отделения мух от котлет.
Когда у меня к примеру есть класс User и есть DataTemplate User, Я могу применять его в любой части программы зацепив из ресурсов в нужный файл, мне при этом не нужно задумываться о том, в каком именно визуальном дереве должен находится данный элемент.

Как по мне, самый верный путь в данном примере, это переопределить шаблон элемента списка, для этого надо задать свойству ListBox.ItemContainerStyle стиль для элемента ListBoxItem, в стиле определить шаблон, который будет содержать ContentPresenter, в качестве шаблона для этого презентера будет выступать ItemTemplate или ItemTemplateSelector, а Content элемент коллекции.

Не надо забывать еще 1 момент, при виртуализации элементы ListBoxItem существуют только в видимой части экрана (+/- n элементов), делая вот такие вот сложные финты в относительными источниками связывания, можно хапнуть горя.
...
Рейтинг: 0 / 0
12.04.2016, 15:28
    #39213759
13th
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListBox - ещё вопрос по фону
Roman Mejtes2 пути:
А) переопределить системный ресурс кисти для выделенных элементов в области ListBox
Б) переопределить шаблон ListBoxItem и задать свой триггер на IsSelect

Вот вариант А я уже где-то видел, сейчас попробую.

Вариант Б - а я разве не то же самое делал? См. мои 1й и 3й посты?
...
Рейтинг: 0 / 0
12.04.2016, 15:49
    #39213800
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListBox - ещё вопрос по фону
Вариант №1:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Page.Resources>
      <ControlTemplate x:Key="ListBoxItemTemplate" TargetType="{x:Type ListBoxItem}">
        <Border Background="{TemplateBinding Background}"
                BorderThickness="{TemplateBinding BorderThickness}"
                BorderBrush="{TemplateBinding BorderBrush}"
                Padding="{TemplateBinding Padding}">
            <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
        </Border>
    </ControlTemplate>
    
      <Style x:Key="listItemStyle" TargetType="{x:Type ListBoxItem}">
        <Setter Property="Padding" Value="0" />
        <Setter Property="BorderThickness" Value="0" />
        <Setter Property="Template" Value="{StaticResource ListBoxItemTemplate}"/>
        <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="Background" Value="Green"/>
            </Trigger>
        </Style.Triggers>
    </Style>
    </Page.Resources>
  <Grid>  
    <ListBox ItemContainerStyle="{StaticResource listItemStyle}">
    <ListBoxItem>Roman</ListBoxItem>
    <ListBoxItem>Sofia</ListBoxItem>
    <ListBoxItem>Olga</ListBoxItem>
    <ListBoxItem>Alexandr</ListBoxItem>
    </ListBox>
  </Grid>
</Page>



Вариант №2
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Page.Resources>
      <ControlTemplate x:Key="ListBoxItemTemplate" TargetType="{x:Type ListBoxItem}">
        <Border x:Name="PART_Border" Background="{TemplateBinding Background}"
                BorderThickness="{TemplateBinding BorderThickness}"
                BorderBrush="{TemplateBinding BorderBrush}"
                Padding="{TemplateBinding Padding}">
            <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                              VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
        </Border>
        <ControlTemplate.Triggers>
            <Trigger Property="IsSelected" Value="True">
                <Setter TargetName="PART_Border" Property="Background" Value="Green"/>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
    
      <Style x:Key="listItemStyle" TargetType="{x:Type ListBoxItem}">
        <Setter Property="Padding" Value="0" />
        <Setter Property="BorderThickness" Value="0" />
        <Setter Property="Template" Value="{StaticResource ListBoxItemTemplate}"/>
    </Style>
    </Page.Resources>
  <Grid>  
    <ListBox ItemContainerStyle="{StaticResource listItemStyle}">
    <ListBoxItem>Roman</ListBoxItem>
    <ListBoxItem>Sofia</ListBoxItem>
    <ListBoxItem>Olga</ListBoxItem>
    <ListBoxItem>Alexandr</ListBoxItem>
    </ListBox>
  </Grid>
</Page>



Вариант №3:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
	<Page.Resources>
		<ControlTemplate x:Key="ListBoxItemTemplate" TargetType="{x:Type ListBoxItem}">
			<Border x:Name="PART_Border" Background="{TemplateBinding Background}"
						BorderThickness="{TemplateBinding BorderThickness}"
						BorderBrush="{TemplateBinding BorderBrush}"
						Padding="{TemplateBinding Padding}">
				<VisualStateManager.VisualStateGroups>
					<VisualStateGroup  x:Name="SelectionStates">
						<VisualState x:Name="Selected">
							<Storyboard>
								<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_Border" Storyboard.TargetProperty="Background">
									<DiscreteObjectKeyFrame KeyTime="0" >
										<DiscreteObjectKeyFrame.Value>
											<SolidColorBrush Color="Green"/>
										</DiscreteObjectKeyFrame.Value>
									</DiscreteObjectKeyFrame>
								</ObjectAnimationUsingKeyFrames>
							</Storyboard>
						</VisualState>
						<VisualState x:Name="Unselected">
							<Storyboard>
								<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_Border" Storyboard.TargetProperty="Background">
									<DiscreteObjectKeyFrame KeyTime="0" >
										<DiscreteObjectKeyFrame.Value>
											<SolidColorBrush Color="{TemplateBinding Background}"/>
										</DiscreteObjectKeyFrame.Value>
									</DiscreteObjectKeyFrame>
								</ObjectAnimationUsingKeyFrames>
							</Storyboard>
						</VisualState>
					</VisualStateGroup>
				</VisualStateManager.VisualStateGroups>
				<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
										   VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
			</Border>
		</ControlTemplate>

		<Style x:Key="listItemStyle" TargetType="{x:Type ListBoxItem}">
			<Setter Property="Padding" Value="0" />
			<Setter Property="BorderThickness" Value="0" />
			<Setter Property="Template" Value="{StaticResource ListBoxItemTemplate}"/>
		</Style>
	</Page.Resources>
	<Grid>  
		<ListBox ItemContainerStyle="{StaticResource listItemStyle}">
			<ListBoxItem>Roman</ListBoxItem>
			<ListBoxItem>Sofia</ListBoxItem>
			<ListBoxItem>Olga</ListBoxItem>
			<ListBoxItem>Alexandr</ListBoxItem>
		</ListBox>
	</Grid>
</Page>
...
Рейтинг: 0 / 0
12.04.2016, 18:31
    #39213987
13th
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListBox - ещё вопрос по фону
Все три метода работают, Роман, спасибо. Вот как бы ещё сделать, что бы фон не менялся, если фокус с листа ушёл?
...
Рейтинг: 0 / 0
12.04.2016, 18:33
    #39213990
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListBox - ещё вопрос по фону
13thВсе три метода работают, Роман, спасибо. Вот как бы ещё сделать, что бы фон не менялся, если фокус с листа ушёл?
разве в моих примерах он меняется?
...
Рейтинг: 0 / 0
13.04.2016, 13:05
    #39214599
13th
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ListBox - ещё вопрос по фону
Roman Mejtesразве в моих примерах он меняется?
Нет, не меняется. Я в первый раз не правильно скопипастил, поэтому у меня криво заработало. Сейчас поковырялся - всё норм стало.
...
Рейтинг: 0 / 0
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / ListBox - ещё вопрос по фону / 15 сообщений из 15, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]