C# CharacterEllipsis在ItemsControl WPF中不起作用

C# CharacterEllipsis在ItemsControl WPF中不起作用,c#,wpf,textblock,texttrimming,C#,Wpf,Textblock,Texttrimming,我试图在ItemsControl的DataTemplate内的文本上设置CharacterEllipsis 澄清 当文本太大时,这种方法非常有效,但我希望当窗口的宽度变小时,这种方法也能起作用。将x:Key添加到样式中,然后像这样设置TextBlock的样式:Rohit Vats已经说明了原因 然后移除stackpanel或设置textblock的宽度 结果: 我的测试代码是: 另一个结果是:调整窗口大小 代码: 将x:Key添加到样式中,并如下设置TextBlock的样式:Rohit Vats

我试图在ItemsControl的DataTemplate内的文本上设置CharacterEllipsis

澄清 当文本太大时,这种方法非常有效,但我希望当窗口的宽度变小时,这种方法也能起作用。

将x:Key添加到样式中,然后像这样设置TextBlock的样式:Rohit Vats已经说明了原因

然后移除stackpanel或设置textblock的宽度

结果:

我的测试代码是:

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

代码:

将x:Key添加到样式中,并如下设置TextBlock的样式:Rohit Vats已经说明了原因

然后移除stackpanel或设置textblock的宽度

结果:

我的测试代码是:

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

代码:


这是一个相当大胆的说法,而且是不真实的。甚至不需要将代码复制到新项目中,我就可以理解为什么会出现这个问题。为了让CharacterElliption工作,TextBlock需要对其宽度施加一些约束。。。否则,WPF如何知道何时开始字符省略号效果

一种解决方案是在文本块上设置精确的宽度:

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


这是一个相当大胆的说法,而且是不真实的。甚至不需要将代码复制到新项目中,我就可以理解为什么会出现这个问题。为了让CharacterElliption工作,TextBlock需要对其宽度施加一些约束。。。否则,WPF如何知道何时开始字符省略号效果

一种解决方案是在文本块上设置精确的宽度:

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


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上设置最大宽度,而不是设置宽度:


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上设置最大宽度,而不是设置宽度:

简短答复:

删除数据模板中的stackpanel:

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

斯蒂安

简短回答:

删除数据模板中的stackpanel:

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


Stian

-1如果没有x:Key指令集,样式将隐式应用于范围内的所有文本块。请参阅我对@RohitVatso的最后一条评论。当文本太大时,此效果确实有效,但当窗口大小调整为较小宽度时,如何使其有效?@Omribitan查看我的更新。移除stackpanle和textblock的宽度,则窗口将更改textblock的大小。-1,不设置x:Key指令,该样式将隐式应用于范围内的所有文本块。请参阅我对@RohitVatso的最后一条评论。当文本太大时,此项功能确实有效,但当窗口大小调整为较小宽度时,如何使其有效?@Omribitan请参阅我的更新。删除stackpanle和textblock的宽度,然后textblock的大小将随窗口而改变。我不是说它不起作用,我是说它对我不起作用。而且,正如我在帖子中所说,我已经尝试过了,但仍然没有成功。我还删除了stackPanel作为ItemsPanel,但它仍然不起作用,这很不寻常。。。给我一点时间把它复制到一个新的项目来测试。它确实有效。。。也许你应该在一个新项目中尝试一下。。。很明显,你要么没有遵循这个正确的建议,要么你有干扰正常行为的额外因素。我已经在一个新项目中对其进行了测试,可以确认这三种解决方案都能正常工作。请确保按照最初的建议移除StackPanels。抱歉,之前没有清除。当文本太大时,它确实可以工作,但我正在寻找一种方法,当窗口调整到较小的宽度时裁剪文本…我不是说它不工作,我是说它不适合我。而且,正如我在帖子中所说,我已经尝试过了,但仍然没有成功。我还删除了stackPanel作为ItemsPanel,但它仍然不起作用,这很不寻常。。。给我一点时间把它复制到

要测试的新项目。它确实有效。。。也许你应该在一个新项目中尝试一下。。。很明显,你要么没有遵循这个正确的建议,要么你有干扰正常行为的额外因素。我已经在一个新项目中对其进行了测试,可以确认这三种解决方案都能正常工作。请确保按照最初的建议移除StackPanels。抱歉,之前没有清除。当文本太大时它确实可以工作,但我正在寻找一种方法,在窗口调整到较小宽度时裁剪文本…是的,在DataTemplate.Resources或Application.Resources中设置样式。或set x:key我已经尝试过了,甚至删除了样式,直接应用了文本修剪,但仍然没有效果。用当前代码更新了我的帖子发布的代码对我尝试过的小样本确实有效。你看到被裁剪的文本了吗?问题在您的代码中的某个地方。更新了重新调整注释大小的答案。看看现在是否可行。如果调整窗口大小会限制TextBlock.Width,则实际上不需要设置任何Width或MaxWidth属性即可实现此功能。是的,请在DataTemplate.Resources或Application.Resources中设置样式。或set x:key我已经尝试过了,甚至删除了样式,直接应用了文本修剪,但仍然没有效果。用当前代码更新了我的帖子发布的代码对我尝试过的小样本确实有效。你看到被裁剪的文本了吗?问题在您的代码中的某个地方。更新了重新调整注释大小的答案。现在看看这是否可行。如果调整窗口大小会限制TextBlock.Width,则实际上不需要设置任何Width或MaxWidth属性即可实现此功能。请查看其余答案的编辑和注释。它不工作。@Omribitan我在这里的post按钮上有点慢,电话铃响了,Rohit更快了。不管怎样,这在这里很好用。阅读他关于stackpanel的评论。它不会包装,因为它会占用所有可用空间。您确定列表中有内容吗?您的列表是否实现了INotifyPropertyChanged或是DO?请查看其余答案的编辑和注释。它不工作。@Omribitan我在这里的post按钮上有点慢,电话铃响了,Rohit更快了。不管怎样,这在这里很好用。阅读他关于stackpanel的评论。它不会包装,因为它会占用所有可用空间。您确定列表中有内容吗?您的列表实现了INotifyPropertyChanged还是DO?哇!你现在才提到你问题的关键部分???在4个人花了半个小时试图帮助你之后?@Sheridan,对不起。有时我在解释我自己时有点困难:/事实上,我刚刚测试过,这也没什么区别。。。我很难让它工作。。。即使使用StackPanel作为ItemsPanelTemplate。@Omribitan如何定义Person类?列表是如何定义的,在哪里定义的?哇!你现在才提到你问题的关键部分???在4个人花了半个小时试图帮助你之后?@Sheridan,对不起。有时我在解释我自己时有点困难:/事实上,我刚刚测试过,这也没什么区别。。。我很难让它工作。。。即使使用StackPanel作为ItemsPanelTemplate。@Omribitan如何定义Person类?列表是如何定义的,在哪里定义的?
<DataTemplate DataType="{x:Type local:Person}">

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

        </DataTemplate>
<TextBlock Text="{Binding Name}" Margin="100,0,0,0" Width="200" />
<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>
<TextBlock Text="{Binding}" TextTrimming="CharacterEllipsis" Margin="100,0,0,0"/>
<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"/>
<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>
<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 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));
    }
}
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));
    }
}