1

我正在尝试CharacterEllipsisDataTemplate.ItemsControl

<Window x:Class="CustomPanel.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CustomPanel;assembly="
Title="Window1" Height="400" Width="400">
<Window.Resources>
    <Style TargetType="{x:Type TextBlock}">
        <Setter Property="TextTrimming" Value="CharacterEllipsis"></Setter>
    </Style>

    <DataTemplate DataType="{x:Type local:Person}">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Name}"
                       Margin="100,0,0,0"/>
        </StackPanel>
    </DataTemplate>
</Window.Resources>

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>

    <ItemsControl ItemsSource="{Binding Persons}" 
                  Grid.Column="0">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

</Grid>

我也尝试将宽度设置为ItemsControl,StackPanelTextBlock本身。

有任何想法吗?

编辑

为了增强这不是 theStyle或 the的问题StackPanel,我将两者都删除了,但它仍然不起作用

<Window.Resources>
    <DataTemplate DataType="{x:Type local:Person}">
            <TextBlock Text="{Binding Name}"
                       TextTrimming="CharacterEllipsis"
                       Margin="100,0,0,0"
                       Width="200"/>
    </DataTemplate>
</Window.Resources>

<Grid>
    <ItemsControl ItemsSource="{Binding Persons}"/>
</Grid>

澄清

当文本太大时,这非常有效,但我希望它在窗口也被调整为更小的宽度时也能正常工作。

4

4 回答 4

3

DataTemplate 不会从窗口中选择样式,因为它不在该范围内。将样式移到DataTemplate.ResourcesOr内部Application.Resources,以便它可以被 DataTemplate 中的 TextBlock 拾取。

其次,您将 TextBlock 包装在 StackPanel 中,使其具有无限大小以进行扩展。因此,删除包装 TextBlock 的 Stackpanel

第三,约束 ItemsControl 的宽度或根据需要设置 MaxWidth。

<Window.Resources>
    <DataTemplate DataType="{x:Type local:Person}">
        <DataTemplate.Resources>
            <Style TargetType="{x:Type TextBlock}">
                <Setter Property="TextTrimming" Value="CharacterEllipsis"/>
            </Style>
        </DataTemplate.Resources>
        <TextBlock Text="{Binding Name}"/>
    </DataTemplate>
</Window.Resources>
<ItemsControl ItemsSource="{Binding Persons}" Width="30">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

更新:

如果您想让它适用于重新调整窗口大小,而不是设置宽度,请在 TextBlock 上设置最大宽度

<Window.Resources>
    <DataTemplate DataType="{x:Type local:Person}">
        <TextBlock Text="{Binding Name}" MaxWidth="200"
                    TextTrimming="CharacterEllipsis"/>
    </DataTemplate>
</Window.Resources>
<ItemsControl Margin="100,0,0,0" ItemsSource="{Binding Persons}"/>
于 2014-08-19T08:35:45.840 回答
1

添加x:Key到样式并像这样设置TextBlock的样式:(Rohit Vats已经说过原因)

<Style x:Key="tb" TargetType="{x:Type TextBlock}">
    <Setter Property="TextTrimming" Value="CharacterEllipsis"></Setter>
</Style>

<DataTemplate DataType="{x:Type local:Person}">
    <StackPanel Orientation="Horizontal">
        <TextBlock Width="90" Style="{DynamicResource tb}" Text="{Binding Name}"
               Margin="100,0,0,0"/>
    </StackPanel>
</DataTemplate>

然后删除堆栈面板或设置文本块的宽度。

结果:

在此处输入图像描述

我的测试代码是:

            Persons = new List<Person>();
            Person p = new Person();
            p.Name="One\ntwo two\nThree Three Three\nfour four four four";
            Persons.Add(p);

另一个结果:(调整窗口大小)

在此处输入图像描述

代码:

<DataTemplate DataType="{x:Type local:Person}">

                <TextBlock Style="{DynamicResource tb}" Text="{Binding Name}"
                       Margin="100,0,0,0"/>

        </DataTemplate>
于 2014-08-19T08:26:41.103 回答
0

这是一个非常大胆的声明,而且是不真实的。甚至无需将您的代码复制到一个新项目中,我就能明白您为什么会遇到这个问题。为了CharacterEllipsis使其正常工作,TextBlock需要对其施加一些约束Width……否则,WPF 将如何知道何时启动字符省略号效果?

一种解决方案是WidthTextBlock:

<TextBlock Text="{Binding Name}" Margin="100,0,0,0" Width="200" />

当然,这对很多人来说并不方便,所以另一种选择是使用StackPanelas the ItemsPanelTemplate(或 in the DataTemplate),因为它们会让 theTextBlock无限增长。


更新>>>

好的,您有三种可能的解决方案,因为它们Style超出了生成DataTemplate元素的范围:

a) 将Style移入DataTemplate.Resources

<DataTemplate DataType="{x:Type local:Person}">
    <DataTemplate.Resources>
        <Style TargetType="{x:Type TextBlock}">
            <Setter Property="TextBlock.TextTrimming" Value="CharacterEllipsis" />
        </Style>
    </DataTemplate.Resources>
    <TextBlock Text="{Binding Name}" Margin="100,0,0,0"/>
</DataTemplate>

b) 将TextTrimming属性直接添加到TextBlock

<TextBlock Text="{Binding}" TextTrimming="CharacterEllipsis" Margin="100,0,0,0"/>

c)明确 Style设置:TextBlock

<Style x:Key="YourStyle" TargetType="{x:Type TextBlock}">
    <Setter Property="TextBlock.TextTrimming" Value="CharacterEllipsis" />
</Style>

<TextBlock Style="{StaticResource YourStyle}" Text="{Binding}" Margin="100,0,0,0"/>
于 2014-08-19T08:26:49.780 回答
0

简短的回答:

删除数据模板中的堆栈面板:

    <DataTemplate DataType="{x:Type local:Person}">
            <TextBlock Text="{Binding Name}" TextTrimming="CharacterEllipsis"/>
    </DataTemplate>

堆栈面板占用了它想要的任何空间,因此修剪不起作用。

长答案:

设置数据上下文的示例:

<Window.DataContext>
   <local:PersonsViewModel/>
</Window.DataContext>

简单的虚拟机:

public class PersonsViewModel : INotifyPropertyChanged
{
    private ObservableCollection<Person> persons = new ObservableCollection<Person> { new Person { Name = "Bjarne balblablalblalbal balbalbalballblalbla" }, new Person { Name = "Arne Belinda blblabllalbalblllablalbla Arne Belinda blblabllalbalblllablalbla Arne Belinda blblabllalbalblllablalbla Arne Belinda blblabllalbalblllablalbla Arne Belinda blblabllalbalblllablalbla" }, new Person { Name = "Turid" } };
    public ObservableCollection<Person> Persons
    {
        get { return persons; }
        set
        {
            if (Equals(value, persons)) return;
            persons = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator] // No R#? Comment this line out
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

Person 类还必须实现 INotifyPropertyChanged 以发出属性更改的信号。

public class Person : INotifyPropertyChanged
{
    private string name;
    public String Name
    {
        get { return name; }
        set
        {
            if (value == name) return;
            name = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

干杯

斯蒂安

于 2014-08-19T08:41:12.107 回答