【问题标题】:CharacterEllipsis doesn't work inside ItemsControl WPFCharacterEllipsis 在 ItemsControl WPF 中不起作用
【发布时间】:2014-10-12 06:21:36
【问题描述】:

我正在尝试在 ItemsControlDataTemplate 内的文本上设置 CharacterEllipsis

<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>

我还尝试将宽度设置为 ItemsControlStackPanelTextBlock 本身。

有什么想法吗?

编辑

为了强调这不是 StyleStackPanel 的问题,我将两者都删除了,但它仍然不起作用

<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 个人花了半个小时试图帮助你之后?
  • @Sheridan 对不起。有时我在解释自己时有点问题:/
  • 实际上,我刚刚测试过,但这也没有什么区别...我在让它工作时遇到了麻烦...甚至 StackPanel 作为ItemsPanelTemplate
  • @Omribitan Person 类是如何定义的?列表是如何定义的,在哪里定义的?

标签: c# wpf textblock texttrimming


【解决方案1】:

简答:

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

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

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

长答案:

设置datacontext示例:

<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));
    }
}

干杯

斯蒂安

【讨论】:

  • 请查看其余答案的编辑和 cmets。它不起作用。
  • @Omribitan 我在这里发帖按钮有点慢,电话响了,Rohit 更快。无论如何,这在这里工作得很好。阅读他关于堆栈面板的 cmets。它不会包装,因为它消耗了所有可用空间。您确定您的列表中有内容吗?您的列表是实现 INotifyPropertyChanged 还是 DO?
【解决方案2】:

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>

【讨论】:

  • -1 如果没有设置x:Key 指令,Style 将隐式应用于范围内的所有TextBlocks。
  • 查看我对@RohitVats 的最后评论
  • 因此,当文本太大时,这个事实确实有效,但是当窗口被调整为更小的宽度时,我怎样才能使它工作?
  • @Omribitan 查看我的更新。移除 stackpanle 和 textblock 的宽度,然后 textblock 的大小将由窗口改变。
【解决方案3】:

DataTemplate 不会从窗口中选择样式,因为它不在该范围内。将样式移动到 DataTemplate.ResourcesApplication.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}"/>

【讨论】:

  • 是的,在 DataTemplate.Resources 或 Application.Resources 中设置样式。或设置 x:key
  • 我已经尝试过了,甚至删除了样式并直接应用了文本修剪,但仍然没有效果。用当前代码更新了我的帖子
  • 发布的代码绝对适用于我尝试过的小样本。你看到裁剪的文本吗?问题出在您的代码中。
  • 更新了调整评论大小的答案。看看现在是否可行。
  • 如果调整Window 的大小限制了TextBlock.Width,则实际上不需要设置任何WidthMaxWidth 属性来完成这项工作。
【解决方案4】:

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

一种解决方案是在TextBlock 上设置一个精确的Width

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

当然,这对很多人来说并不方便,所以一个替代方法是使用StackPanel 作为ItemsPanelTemplate(或在DataTemplate),因为他们会让TextBlock无限增长。


更新>>>

好的,您有三种可能的解决方案,因为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) 在TextBlock 上明确设置Style

<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"/>

【讨论】:

  • 我并不是说它不起作用,我的意思是它对我不起作用。另外,正如我在帖子中所说的那样,我已经尝试过了,但它仍然没有用。我还删除了 stackPanel 作为 ItemsPanel ,它仍然不影响
  • 好吧,这很不寻常……给我一点时间把它复制到一个新项目中进行测试。
  • 确实工作......也许应该在一个新项目中尝试它......显然你要么不 i> 遵循这个正确的建议,或者您有其他干扰正常行为的元素。我已经在一个新项目中对其进行了测试,并且可以确认所有这三种解决方案确实有效。确保按照最初的建议删除 StackPanels。
  • 抱歉之前没有说清楚。当文本太大时它确实有效,但我正在寻找一种在窗口调整为较小宽度时裁剪文本的方法......
猜你喜欢
  • 2011-07-11
  • 2020-05-31
  • 1970-01-01
  • 1970-01-01
  • 2015-12-09
  • 1970-01-01
  • 1970-01-01
  • 2012-07-30
  • 2011-07-31
相关资源
最近更新 更多