3 回答

TA貢獻2036條經驗 獲得超8個贊
我有一個簡單的解決方案DataTemplateSelector。它是這樣的:
您定義一個選擇器,用于區分最后一項。
class LastElementSelector : DataTemplateSelector
{
public DataTemplate NormalTemplate { get; set; }
public DataTemplate LastTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
return IsLast(container) ? LastTemplate : NormalTemplate;
}
bool IsLast(DependencyObject container)
{
var itemsControl = FindParentOrSelf<ItemsControl>(container);
var idx = itemsControl.ItemContainerGenerator.IndexFromContainer(container);
var count = itemsControl.Items.Count;
return idx == count - 1;
}
T FindParentOrSelf<T>(DependencyObject from) where T : DependencyObject
{
for (var curr = from; curr != null; curr = VisualTreeHelper.GetParent(curr))
if (curr is T t)
return t;
return null;
}
}
有了這個,您可以對普通項目和最后項目使用不同的模板:
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplateSelector>
<local:LastElementSelector>
<local:LastElementSelector.NormalTemplate>
<DataTemplate>
<TextBlock>
<Run Text="{Binding Mode=OneWay}"/><!-- no space between runs
--><Run Text="; " Foreground="Red" FontWeight="Bold"/>
</TextBlock>
</DataTemplate>
</local:LastElementSelector.NormalTemplate>
<local:LastElementSelector.LastTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</local:LastElementSelector.LastTemplate>
</local:LastElementSelector>
</ItemsControl.ItemTemplateSelector>
</ItemsControl>
結果:
https://i.stack.imgur.com/RIcQR.gif

TA貢獻1898條經驗 獲得超8個贊
您的定界符位于下一行的前面,因為它位于 LinkId TextBox 的前面,并且它們都在 WrapPanel 中綁定在一起。整個 WrapPanel 流向下一行。
WrapPanels 上方的父面板不知道也不關心其中的內容。
順便說一下,我不知道這是否是您的意圖,但在您編寫的代碼中,您為集合中的每個項目生成了一個不同的 WrapPanel。目前,您的測試列表中有 20 個 WrapPanel。
如果像您所說的那樣,最后一個分隔符不是問題,那么這是一個足夠好的解決方案:
<ItemsControl
ItemsSource="{Binding YourItems}"
>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel
Orientation="Horizontal"
></WrapPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel
Orientation="Horizontal"
>
<TextBlock
Text="{Binding LinkId}"
></TextBlock>
<TextBlock
Text="; "
></TextBlock>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
如果這僅用于數據顯示目的,請考慮那些行中的文本框很可能是文本框內的單個字符串。也許您可以使用單一格式的字符串并將相關部分制作成鏈接。這會將操作的字符串分隔符部分移至 ViewModel,并會大大簡化您的 XAML 代碼。

TA貢獻1780條經驗 獲得超5個贊
您可以嘗試將定界符放在文本之后,并通過將其屬性設置為空字符串來隱藏最后一個Run元素:Text
<ItemsControl AlternationCount="{Binding RelativeSource={RelativeSource Self}, Path=Items.Count}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock>
<Run Text="{Binding Path=., Mode=OneWay}" /><Run x:Name="delimiter" Text="; "/>
</TextBlock>
<DataTemplate.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Text" TargetName="delimiter" Value=""/>
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
這應該使分隔符和文本保持在同一行。
- 3 回答
- 0 關注
- 159 瀏覽
添加回答
舉報