CharacterEllipsis在ItemsControl WPF中不起作用

时间:2014-08-19 08:09:21

标签: c# wpf textblock texttrimming

我正在尝试在CharacterEllipsis的{​​{1}}内的文字上设置DataTemplate

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> ItemsControlStackPanel本身。

任何想法?

修改

为了强调这不是TextBlockStyle的问题,我删除了它们仍然无效

StackPanel

澄清

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

4 个答案:

答案 0 :(得分:3)

DataTemplate不会从窗口中选择样式,因为它不在该范围内。在 DataTemplate.Resources Application.Resources 内移动样式,以便DataTemplate中的TextBlock可以选择该样式。

其次,你已经在StackPanel中包装了TextBlock,这使得它可以扩展无限大小。因此, 删除包装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}"/>

答案 1 :(得分: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>

然后删除stackpanel或设置textblock的宽度。

<强>结果:

enter image description here

,我的测试代码为:

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

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

enter image description here

<强>码

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

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

        </DataTemplate>

答案 2 :(得分:0)

这是一个非常大胆的陈述,也是一个不真实的陈述。甚至没有将代码复制到新项目中,我可以看出为什么会遇到这个问题。为了使CharacterEllipsis起作用,TextBlock需要在其Width上设置一些约束...否则,WPF将如何知道何时开始字符省略号效果?

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

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

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


更新&gt;&gt;&gt;

好的,您有三种可能的解决方案,因为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"/>

答案 3 :(得分:0)

简答:

删除datatemplate中的stackpanel:

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

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

答案很长:

设置datacontext的示例:

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

简单vm:

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

干杯

了Stian