ItemsControl의 항목 사이에 구분 기호를 추가하는 방법
항목 컨트롤에 컬렉션의 번호 목록을 표시해야 합니다.항목은 다음과 같습니다."1", "2", "3"
.
렌더링할 때 쉼표(또는 비슷한 것)로 구분해야 합니다.위의 3가지 항목은 다음과 같습니다."1, 2, 3"
.
목록 끝에 구분자를 붙이지 않고 개별 항목에 구분자를 추가하려면 어떻게 해야 합니까?
Items Control을 사용하는 것에 집착하는 것은 아니지만, 그것을 사용하기 시작했습니다.
<ItemsControl ItemsSource="{Binding Numbers}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<!-- could use a WrapPanel if more appropriate for your scenario -->
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="commaTextBlock" Text=", "/>
<TextBlock Text="{Binding .}"/>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource PreviousData}}" Value="{x:Null}">
<Setter Property="Visibility" TargetName="commaTextBlock" Value="Collapsed"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Silverlight에서 솔루션을 찾고 있었기 때문에 질문하신 내용에 도달했습니다.Silverlight에는 이전 데이터 관련 소스가 없습니다.
현재 승인된 답변으로 인해 템플릿마다 xaml 바인딩 오류가 발생했으며, 이 오류가 성능에 영향을 줄 수 있습니다.대신 Alternation을 사용하여 다음 작업을 수행했습니다.첫 번째 구분 기호를 숨기는 색인입니다.(이 답변에서 영감을 얻음)
<ItemsControl ItemsSource="{Binding Numbers}" AlternationCount="{Binding RelativeSource={RelativeSource Self}, Path=Items.Count}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="SeparatorTextBlock" Text=", "/>
<TextBlock Text="{Binding .}"/>
</StackPanel>
<DataTemplate.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Visibility" TargetName="SeparatorTextBlock" Value="Collapsed" />
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
보다 일반적인 Silverlight 호환 솔루션을 위해 Items Control (별도)에서 컨트롤을 취득했습니다.Items Control)을 클릭합니다.각 아이템은 별도 포장으로 포장되어 있습니다.ListBox의 ListBoxItem과 같은 ItemsControlItem.분리 템플릿ItemsControlItem에는 구분자와 ContentPresenter가 포함되어 있습니다.컬렉션의 첫 번째 요소에 대한 구분자가 숨겨집니다.이 솔루션을 쉽게 수정하여 아이템 사이에 가로 막대 분리기를 만들 수 있습니다.그 때문에 이 솔루션을 만들었습니다.
Main Window.xaml:
<Window x:Class="ItemsControlWithSeperator.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ItemsControlWithSeperator"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.Resources>
<local:ViewModel x:Key="vm" />
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White" DataContext="{StaticResource vm}">
<local:SeperatedItemsControl ItemsSource="{Binding Data}">
<local:SeperatedItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</local:SeperatedItemsControl.ItemsPanel>
<local:SeperatedItemsControl.ItemContainerStyle>
<Style TargetType="local:SeperatedItemsControlItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:SeperatedItemsControlItem" >
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="seperator">,</TextBlock>
<ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</local:SeperatedItemsControl.ItemContainerStyle>
</local:SeperatedItemsControl>
</Grid>
C# 코드:
using System;
using System.Windows;
using System.Windows.Controls;
namespace ItemsControlWithSeperator
{
public class ViewModel
{
public string[] Data { get { return new[] { "Amy", "Bob", "Charlie" }; } }
}
public class SeperatedItemsControl : ItemsControl
{
public Style ItemContainerStyle
{
get { return (Style)base.GetValue(SeperatedItemsControl.ItemContainerStyleProperty); }
set { base.SetValue(SeperatedItemsControl.ItemContainerStyleProperty, value); }
}
public static readonly DependencyProperty ItemContainerStyleProperty =
DependencyProperty.Register("ItemContainerStyle", typeof(Style), typeof(SeperatedItemsControl), null);
protected override DependencyObject GetContainerForItemOverride()
{
return new SeperatedItemsControlItem();
}
protected override bool IsItemItsOwnContainerOverride(object item)
{
return item is SeperatedItemsControlItem;
}
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
//begin code copied from ListBox class
if (object.ReferenceEquals(element, item))
{
return;
}
ContentPresenter contentPresenter = element as ContentPresenter;
ContentControl contentControl = null;
if (contentPresenter == null)
{
contentControl = (element as ContentControl);
if (contentControl == null)
{
return;
}
}
DataTemplate contentTemplate = null;
if (this.ItemTemplate != null && this.DisplayMemberPath != null)
{
throw new InvalidOperationException();
}
if (!(item is UIElement))
{
if (this.ItemTemplate != null)
{
contentTemplate = this.ItemTemplate;
}
}
if (contentPresenter != null)
{
contentPresenter.Content = item;
contentPresenter.ContentTemplate = contentTemplate;
}
else
{
contentControl.Content = item;
contentControl.ContentTemplate = contentTemplate;
}
if (ItemContainerStyle != null && contentControl.Style == null)
{
contentControl.Style = ItemContainerStyle;
}
//end code copied from ListBox class
if (this.Items.Count > 0)
{
if (object.ReferenceEquals(this.Items[0], item))
{
var container = element as SeperatedItemsControlItem;
container.IsFirstItem = true;
}
}
}
protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
base.OnItemsChanged(e);
if (Items.Count > 1)
{
var container = (ItemContainerGenerator.ContainerFromIndex(1) as SeperatedItemsControlItem);
if (container != null) container.IsFirstItem = false;
}
if (Items.Count > 0)
{
var container = (ItemContainerGenerator.ContainerFromIndex(0) as SeperatedItemsControlItem);
if (container != null) container.IsFirstItem = true;
}
}
}
public class SeperatedItemsControlItem : ContentControl
{
private bool isFirstItem;
public bool IsFirstItem
{
get { return isFirstItem; }
set
{
if (isFirstItem != value)
{
isFirstItem = value;
var seperator = this.GetTemplateChild("seperator") as FrameworkElement;
if (seperator != null)
{
seperator.Visibility = isFirstItem ? Visibility.Collapsed : Visibility.Visible;
}
}
}
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
if (IsFirstItem)
{
var seperator = this.GetTemplateChild("seperator") as FrameworkElement;
if (seperator != null)
{
seperator.Visibility = Visibility.Collapsed;
}
}
}
}
}
ItemsControl에 멀티바인드할 수도 있습니다.대체인덱스 및 항목 제어.대체값의 카운트 및 비교Index to Count 사용자가 마지막 항목인지 확인합니다.
대체 설정모든 항목을 수용할 수 있을 정도로 높은 인덱스를 가진 다음 다음과 같은 Convert 메서드를 사용하여 LastItemConverter를 만듭니다.
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var alterationCount = (int)values[0];
var itemCount = (int)values[1];
if (itemCount > 1)
{
return alterationCount == (itemCount - 1) ? Visibility.Collapsed : Visibility.Visible;
}
return Visibility.Collapsed;
}
난 내가 결국 하게 된 해결책을 제시해야겠다고 생각했다.
항목 컬렉션을 텍스트 블록의 텍스트에 바인딩하고 값 변환기를 사용하여 바인딩된 항목 컬렉션을 형식 문자열로 변경했습니다.
언급URL : https://stackoverflow.com/questions/2511227/how-can-a-separator-be-added-between-items-in-an-itemscontrol
'source' 카테고리의 다른 글
Excel의 열에서 고유한 값 카운트 (0) | 2023.04.17 |
---|---|
예외 해결 방법:콜이 착신자에 의해 거부되었습니다.(HRESULT: 0x80010001(RPC_E_CALL_REJECTED)의 예외) (C#) (0) | 2023.04.17 |
팀에 대한 iTunes Connect 액세스 권한이 있는 계정을 찾을 수 없습니다. (0) | 2023.04.17 |
도커 이미지의 새 컨테이너에서 bash를 실행하려면 어떻게 해야 합니까? (0) | 2023.04.17 |
데이터베이스에 대한 모든 연결을 끊는 스크립트(RESTRICTED_USER Rollback 이상) (0) | 2023.04.17 |