TextBlock是一个UI控件,用于在WPF(.NET Framework)中显示少量文本。
我有一个按钮。当鼠标悬停在按钮上时,我的项目中使用的文本块应该显示一些值。按钮是在库和我在项目中使用的库中定义的。在我的项目中我
如何为 TextBlock 内的文本指定垂直居中对齐?我找到了 TextAlignment 属性,但它用于水平文本对齐。如何实现垂直文本对齐?
我正在使用 Textblock.Inlines 来将图片和文本添加到标题元素。无需太深入代码,一个简短的示例是: TextBlock tbHeader = new TextBlock(); 图片标题我...
以下文本块按预期换行和修剪。修剪文本时会显示省略号“...”。 以下文本块按预期换行和修剪。修剪文本时会显示省略号“...”。 <TextBlock MaxWidth="60" MaxHeight="60" Text="This is some long text which I would like to wrap." TextWrapping="Wrap" TextTrimming="CharacterEllipsis" /> 我想在带有全文的文本上显示工具提示,但前提是文本被修剪。我不确定如何可靠地确定是否显示“...”。 如何判断文本是否被修剪? 因为 Alek 答案中的链接已关闭,我从回程机器中找到了链接的缓存副本。您无法下载文章中链接的代码,因此这里是代码的预汇编版本。我在尝试使其工作时遇到了一两个问题,因此此代码与本文示例中的代码略有不同。 using System; using System.Windows; using System.Windows.Controls; using System.Windows.Media; namespace TextBlockService { //Based on the project from http://web.archive.org/web/20130316081653/http://tranxcoder.wordpress.com/2008/10/12/customizing-lookful-wpf-controls-take-2/ public static class TextBlockService { static TextBlockService() { // Register for the SizeChanged event on all TextBlocks, even if the event was handled. EventManager.RegisterClassHandler( typeof(TextBlock), FrameworkElement.SizeChangedEvent, new SizeChangedEventHandler(OnTextBlockSizeChanged), true); } private static readonly DependencyPropertyKey IsTextTrimmedKey = DependencyProperty.RegisterAttachedReadOnly("IsTextTrimmed", typeof(bool), typeof(TextBlockService), new PropertyMetadata(false)); public static readonly DependencyProperty IsTextTrimmedProperty = IsTextTrimmedKey.DependencyProperty; [AttachedPropertyBrowsableForType(typeof(TextBlock))] public static Boolean GetIsTextTrimmed(TextBlock target) { return (Boolean)target.GetValue(IsTextTrimmedProperty); } public static readonly DependencyProperty AutomaticToolTipEnabledProperty = DependencyProperty.RegisterAttached( "AutomaticToolTipEnabled", typeof(bool), typeof(TextBlockService), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.Inherits)); [AttachedPropertyBrowsableForType(typeof(DependencyObject))] public static Boolean GetAutomaticToolTipEnabled(DependencyObject element) { if (null == element) { throw new ArgumentNullException("element"); } return (bool)element.GetValue(AutomaticToolTipEnabledProperty); } public static void SetAutomaticToolTipEnabled(DependencyObject element, bool value) { if (null == element) { throw new ArgumentNullException("element"); } element.SetValue(AutomaticToolTipEnabledProperty, value); } private static void OnTextBlockSizeChanged(object sender, SizeChangedEventArgs e) { TriggerTextRecalculation(sender); } private static void TriggerTextRecalculation(object sender) { var textBlock = sender as TextBlock; if (null == textBlock) { return; } if (TextTrimming.None == textBlock.TextTrimming) { textBlock.SetValue(IsTextTrimmedKey, false); } else { //If this function is called before databinding has finished the tooltip will never show. //This invoke defers the calculation of the text trimming till after all current pending databinding //has completed. var isTextTrimmed = textBlock.Dispatcher.Invoke(() => CalculateIsTextTrimmed(textBlock), DispatcherPriority.DataBind); textBlock.SetValue(IsTextTrimmedKey, isTextTrimmed); } } private static bool CalculateIsTextTrimmed(TextBlock textBlock) { if (!textBlock.IsArrangeValid) { return GetIsTextTrimmed(textBlock); } Typeface typeface = new Typeface( textBlock.FontFamily, textBlock.FontStyle, textBlock.FontWeight, textBlock.FontStretch); // FormattedText is used to measure the whole width of the text held up by TextBlock container FormattedText formattedText = new FormattedText( textBlock.Text, System.Threading.Thread.CurrentThread.CurrentCulture, textBlock.FlowDirection, typeface, textBlock.FontSize, textBlock.Foreground); formattedText.MaxTextWidth = textBlock.ActualWidth; // When the maximum text width of the FormattedText instance is set to the actual // width of the textBlock, if the textBlock is being trimmed to fit then the formatted // text will report a larger height than the textBlock. Should work whether the // textBlock is single or multi-line. // The "formattedText.MinWidth > formattedText.MaxTextWidth" check detects if any // single line is too long to fit within the text area, this can only happen if there is a // long span of text with no spaces. return (formattedText.Height > textBlock.ActualHeight || formattedText.MinWidth > formattedText.MaxTextWidth); } } } <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:tbs="clr-namespace:TextBlockService"> <!-- Rather than forcing *all* TextBlocks to adopt TextBlockService styles, using x:Key allows a more friendly opt-in model. --> <Style TargetType="TextBlock" x:Key="TextBlockService"> <Style.Triggers> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="tbs:TextBlockService.AutomaticToolTipEnabled" Value="True" /> <Condition Property="tbs:TextBlockService.IsTextTrimmed" Value="True"/> </MultiTrigger.Conditions> <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=Text}" /> </MultiTrigger> </Style.Triggers> </Style> </ResourceDictionary> 我最近没有做过很多 WPF,所以我不确定这是否是您正在寻找的内容,但请查看这篇文章:自定义“好看的”WPF 控件 - 采取 2。这有点复杂,但它似乎解决了您所问的同一问题。更新:该网站似乎消失了,但您可以在archive中找到该文章。请参阅 Scott Chamberlain 的示例代码答案(感谢 Scott)。 如果 TextBlock 是 ListBoxItem DataTemplate 的一部分,则上述解决方案对我不起作用。 我提出另一个解决方案: public class MyTextBlock : System.Windows.Controls.TextBlock { protected override void OnToolTipOpening(WinControls.ToolTipEventArgs e) { if (TextTrimming != TextTrimming.None) { e.Handled = !IsTextTrimmed(); } } private bool IsTextTrimmed() { Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); return ActualWidth < DesiredSize.Width; } } XAML: <MyTextBlock Text="{Binding Text}" TextTrimming="CharacterEllipsis" ToolTip="{Binding Text}" /> 扩展 bidy 的答案。这将创建一个 TextBlock,仅在未显示所有文本时显示工具提示。工具提示将根据内容调整大小(与默认工具提示相反,默认工具提示将保留为单行框并截断文本)。 using System; using System.Windows; using System.Windows.Controls; namespace MyComponents { public class CustomTextBlock : TextBlock { protected override void OnInitialized(EventArgs e) { // we want a tooltip that resizes to the contents -- a textblock with TextWrapping.Wrap will do that var toolTipTextBlock = new TextBlock(); toolTipTextBlock.TextWrapping = TextWrapping.Wrap; // bind the tooltip text to the current textblock Text binding var binding = GetBindingExpression(TextProperty); if (binding != null) { toolTipTextBlock.SetBinding(TextProperty, binding.ParentBinding); } var toolTipPanel = new StackPanel(); toolTipPanel.Children.Add(toolTipTextBlock); ToolTip = toolTipPanel; base.OnInitialized(e); } protected override void OnToolTipOpening(ToolTipEventArgs e) { if (TextTrimming != TextTrimming.None) { e.Handled = !IsTextTrimmed(); } } private bool IsTextTrimmed() { Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); return ActualWidth < DesiredSize.Width; } } } XAML 用法: <Window ... xmlns:components="clr-namespace:MyComponents" ... > <components:CustomTextBlock Text="{Binding Details}" TextTrimming="CharacterEllipsis" /> 我在使用 Alex 答案时遇到了一个小问题,必须稍微改变我的逻辑,以澄清文本块中的文本是否被修剪。 var formattedText = new FormattedText( Text, System.Threading.Thread.CurrentThread.CurrentCulture, FlowDirection, typeface, FontSize, Foreground, VisualTreeHelper.GetDpi( this ).PixelsPerDip ) { MaxTextWidth = ActualWidth }; //Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); return ( Math.Floor(formattedText.Height ) > ActualHeight || Math.Floor( formattedText.MinWidth ) > ActualWidth; 这对我来说非常有效。 我定义了一个用户控件,它是启用省略号的 TextBlock。然后我为 OnMouseUp 和 OnMouseDown 定义了 2 个函数,这样当用户单击溢出的文本块时,它将显示带有完整值的工具提示。 这是 OnMouseDown 函数 private void TextBlockWithToolTipView_OnMouseDown( object sender, MouseButtonEventArgs e ) { var typeface = new Typeface( FontFamily, FontStyle, FontWeight, FontStretch); var formattedText = new FormattedText( Text, System.Threading.Thread.CurrentThread.CurrentCulture, FlowDirection, typeface, FontSize, Foreground, VisualTreeHelper.GetDpi( this ).PixelsPerDip ) { MaxTextWidth = ActualWidth }; if (Math.Floor(formattedText.Height) > ActualHeight || Math.Floor(formattedText.MinWidth) > ActualWidth ) { if( ToolTip is ToolTip tt ) { { if( tt.PlacementTarget == null ) { tt.PlacementTarget = this; } tt.IsOpen = true; e.Handled = true; } } } } 这就是 Xaml 位 <TextBlock ToolTipService.IsEnabled="True" MouseDown="TextBlockWithToolTipView_OnMouseDown" MouseLeave="TextBlockWithToolTipView_OnMouseLeave" TextTrimming="CharacterEllipsis" TextWrapping="WrapWithOverflow"> <TextBlock.ToolTip> <ToolTip DataContext="{Binding Path=PlacementTarget, RelativeSource={x:Static RelativeSource.Self}}"> <TextBlock Text="{Binding Path=Text, Mode=OneWay }" TextWrapping="Wrap"/> </ToolTip> </TextBlock.ToolTip> </TextBlock> 基于 Alek Davis 和随后的 Scott Chamberlain 的答案,我想出了他们提到的代码的现代化版本: public static class TextBlockService { static TextBlockService() { // Register for the SizeChanged event on all TextBlocks, even if the event was handled. EventManager.RegisterClassHandler( typeof(TextBlock), FrameworkElement.SizeChangedEvent, new SizeChangedEventHandler(OnTextBlockSizeChanged), handledEventsToo: true); } private static readonly DependencyPropertyKey IsTextTrimmedKey = DependencyProperty.RegisterAttachedReadOnly( "IsTextTrimmed", typeof(bool), typeof(TextBlockService), new PropertyMetadata(false)); public static readonly DependencyProperty IsTextTrimmedProperty = IsTextTrimmedKey.DependencyProperty; [AttachedPropertyBrowsableForType(typeof(TextBlock))] public static bool GetIsTextTrimmed(TextBlock target) { return (bool)target.GetValue(IsTextTrimmedProperty); } public static readonly DependencyProperty AutomaticToolTipEnabledProperty = DependencyProperty.RegisterAttached( "AutomaticToolTipEnabled", typeof(bool), typeof(TextBlockService), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.Inherits)); [AttachedPropertyBrowsableForType(typeof(DependencyObject))] public static bool GetAutomaticToolTipEnabled(DependencyObject element) { ArgumentNullException.ThrowIfNull(element); return (bool)element.GetValue(AutomaticToolTipEnabledProperty); } public static void SetAutomaticToolTipEnabled(DependencyObject element, bool value) { ArgumentNullException.ThrowIfNull(element); element.SetValue(AutomaticToolTipEnabledProperty, value); } private static void OnTextBlockSizeChanged(object sender, SizeChangedEventArgs e) { _ = TriggerTextRecalculationAsync(sender); } private static async Task TriggerTextRecalculationAsync(object sender) { if (sender is TextBlock textBlock) { if (textBlock.TextTrimming is TextTrimming.None) { textBlock.SetValue(IsTextTrimmedKey, false); } else { // If this function is called before databinding has finished, the tooltip will never show. // This invoke defers the calculation of the text trimming till after all current pending databinding // has completed. bool isTextTrimmed = await textBlock.Dispatcher.InvokeAsync(() => CalculateIsTextTrimmed(textBlock), DispatcherPriority.DataBind); textBlock.SetValue(IsTextTrimmedKey, isTextTrimmed); } } } private static bool CalculateIsTextTrimmed(TextBlock textBlock) { if (!textBlock.IsArrangeValid) { return GetIsTextTrimmed(textBlock); } var typeface = new Typeface( textBlock.FontFamily, textBlock.FontStyle, textBlock.FontWeight, textBlock.FontStretch); // FormattedText is used to measure the whole width of the text held up by TextBlock container var formattedText = new FormattedText( textBlock.Text, Thread.CurrentThread.CurrentCulture, textBlock.FlowDirection, typeface, textBlock.FontSize, textBlock.Foreground, VisualTreeHelper.GetDpi(textBlock).PixelsPerDip) { MaxTextWidth = textBlock.ActualWidth }; // When the maximum text width of the FormattedText instance is set to the actual // width of the textBlock, if the textBlock is being trimmed to fit then the formatted // text will report a larger height than the textBlock. Should work whether the // textBlock is single or multi-line. // The "formattedText.MinWidth > formattedText.MaxTextWidth" check detects if any // single line is too long to fit within the text area, this can only happen if there is a // long span of text with no spaces. return formattedText.Height > textBlock.ActualHeight || formattedText.MinWidth > formattedText.MaxTextWidth; } } 这个版本修复了我遇到的两个问题: 不带 FormattedText 参数的 pixelsPerDip 构造函数重载现在已过时。 在某些特定情况下,我的性能出现了巨大的下降,而这对于大多数人来说可能是察觉不到的。 关于2:情况是我在TextBlockServices A 的DataTemplate中使用了这些ListBox,大约有10个项目。使用 TextBox 输入和 CollectionViewSource 对其进行过滤。相同的输入还过滤了第二个 ListBox B,它没有使用 TextBlockService,但有大约 2000 个具有复杂模板的项目。 问题是我可以使用过滤器,并且列表将在大约 150 毫秒内更新。但是,一旦我第一次打开列表 B 的某个项目的上下文菜单,过滤就会变得很慢,两次按键之间需要 1.5 秒,直到 UI 更新并再次响应。 我设法通过不断等待 textBlock.Dispatcher.Invoke 中的 TriggerTextRecalculation 调用来识别此服务导致交错 UI 线程循环执行。 起初,这些调用每个项目将花费 0-5 毫秒,但是在打开上下文菜单一次后,每个项目将花费 150-350 毫秒。 我仍然不确定 WPF 背后发生了什么导致这种行为变化,但是使 TriggerTextRecalculation 异步并使用 await ... InvokeAsync 解决了这个问题,将每次调用减少到 10-15 毫秒(因此持续时间“之前”变得更糟了一点,但“之后”得到了很大的改善)。 我修改了不同的变体,例如使 CalculateIsTextTrimmed 异步并在那里等待空回调,或者使用比 DataBind 更低的调度程序优先级,但感觉这些更改中的任何一个都不会影响感知或测量的性能我可怜的人的Stopwatch侧写不精确。 无论如何,我认为它对于我的用例来说“足够好”,所以我现在停止进一步优化。但是,如果有人对发生的情况以及如何将上下文菜单之前和之后的时间始终恢复到 0-5 毫秒有任何见解,请随时发表评论,我将在应用程序中尝试一下。
Windows.UI.Xaml.Controls.TextBlock.DoubleTapped 事件未触发
在适用于 Android 和 UWP 的 Xamarin.Forms 项目中,我想定义长按 (Android) 和双击(在 UWP 上)的效果。为此目的,我做了所有我发现的事情,定义了适当的 RoutingEff...
我在 GroupBox.Header 中使用 TextBlock 将文本拆分为多行。但是,这意味着边框不再与文本完全对齐。文字超出了集团范围......
我有一个绑定到 DateTime 属性的 TextBlock。如何配置日期的格式?
如何在网格视图中使用键盘(例如使用选项卡)关注 XAML WPF 中的 TextBlock?
我有一个文本块,它有一个带有转换器的绑定路径,但我无法使用选项卡按钮操作它。 Textblock 有一个 Onclick 属性,可以打开另一个页面。我想打开那个屏幕...
我想减少 TextBlock 中制表符的宽度。制表符相当于大约 8 个字符。我想减少到大约 4 个空格。 TextBlock 文本块 = 新的 TextBloc...
TextBlock 中的 C# 超链接:单击它时没有任何反应
在我的 C# 独立应用程序中,我想让用户单击一个链接来启动他们最喜欢的浏览器。 System.Windows.Controls.TextBlock 文本 = new TextBlock(); Run run = new Run("链接 Tex...
在 WPF 中使用 RenderTargetBitmap 创建 TextBlock 的 png 图像时出现问题
当使用 RenderTargetBitmap 创建作为 Canvas 子级的 TextBlock 的 png 文件时,文本将拉伸到 TextBlock 的宽度。 TextBlock 作为“Right&qu...
编辑: 下面的代码实际上按照我想要的方式工作 - 这个问题有点误导。请忽略它。 通常当我像这样设置 TextBlock 的 Text 属性时: TextBlock tb = new TextBlock(); TB...
我目前正在练习xaml。我打算用文本框和文本块制作一个简单的菜单。 当我将文本块或文本框拖到画布上时,看起来不错。但我运行程序后却相差甚远...
我使用属性 TextWrapping="Wrap" 设置了一个 WPF 文本块。 当我在开头传递一个带有制表符(在我的例子中为 vbTab)的长字符串时,我希望换行能够尊重...
我有以下代码来设置前景属性 TextBlock 标签 = new TextBlock() { 样式 = LabelStyle }; 绑定绑定 = new Binding(LabelColor) { Source = dataContextProperty }; ...
我有以下 XAML: 我有以下 XAML: <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" TextAlignment="Center" TextWrapping="Wrap" Margin="15"> line1<LineBreak/><LineBreak/> line2 <TextBlock.Style> <Style TargetType="{x:Type TextBlock}"> <Setter Property="Visibility" Value="Hidden"/> <Style.Triggers> <DataTrigger Binding="{Binding State}" Value="ShowText"> <Setter Property="Visibility" Value="Visible"/> </DataTrigger> </Style.Triggers> </Style> </TextBlock.Style> </TextBlock> 但是 Visual Studio 抛出错误 Cannot have both the text 'line1' and the child element 'LineBreak' within a property element. 而且我不知道如何保留换行符并解决问题。我试过这个: <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" TextAlignment="Center" TextWrapping="Wrap" Margin="15"> <TextBlock.Text> line1<LineBreak/><LineBreak/> line2 </TextBlock.Text> <TextBlock.Style> <Style TargetType="{x:Type TextBlock}"> <Setter Property="Visibility" Value="Hidden"/> <Style.Triggers> <DataTrigger Binding="{Binding State}" Value="ShowText"> <Setter Property="Visibility" Value="Visible"/> </DataTrigger> </Style.Triggers> </Style> </TextBlock.Style> </TextBlock> 但是随后出现重复错误“文本属性设置多次”。 将内联放在样式后面: <TextBlock ...> <TextBlock.Style> ... </TextBlock.Style> line1<LineBreak/><LineBreak/> line2 </TextBlock>
在 ComboBox DataTemplate 中获取 TextBlock 的值
我有以下 XAML: 我有以下 XAML: <ComboBox Height="23" HorizontalAlignment="Left" Grid.Row="6" Grid.Column="2" Name="cbo_team" VerticalAlignment="Top" Width="148" DataContext="{Binding ElementName=cbo_component, Path=SelectedItem}" SelectedIndex="0"> <ComboBox.ItemsSource> <Binding XPath="Teams/Team/@id" Converter="{StaticResource xmlConverter}"> <Binding.ConverterParameter> <local:XmlConverterParameter XPathTemplate="/Products/Teams/Team[{0}]" XPathCondition="@id='{0}'" /> </Binding.ConverterParameter> </Binding> </ComboBox.ItemsSource> <ComboBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding XPath=@name}" /> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox> 在 C# 中,我试图获取 TextBlock 中当前选定项中的 ComboBox 的值。我怎么做? 这个问题差不多,但唯一的答案没有帮助。 检查这个样本。文本块(组合框下方)显示组合框中当前选定的 xml 元素的名称属性的值。将弹出一个消息框,其中包含在可视化树中查找的相同结果。初始选择更改时查找失败。看起来组合框项目是在设置所选项目后创建的。 XAML: <Window x:Class="CBTest.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="300" Width="300"> <Window.Resources> <XmlDataProvider x:Key="UsersData" XPath="Users"> <x:XData> <Users xmlns=""> <User name="Sally" /> <User name="Lucy" /> <User name="Linus" /> <User name="Charlie" /> </Users> </x:XData> </XmlDataProvider> </Window.Resources> <StackPanel> <ComboBox Name="_comboBox" ItemsSource="{Binding Source={StaticResource UsersData},XPath=*}" SelectedIndex="0" SelectionChanged="OnComboBoxSelectionChanged"> <ComboBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding XPath=@name}" Name="nameTextBlock" /> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox> <!-- Below shows how to get the value of selected item directly from the data. --> <TextBlock DataContext="{Binding Path=SelectedItem, ElementName=_comboBox}" Text="{Binding XPath=@name}" /> </StackPanel> </Window> 后面的代码,展示了如何通过遍历可视化树直接获取文本: private void OnComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e) { ComboBox comboBox = sender as ComboBox; ComboBoxItem comboBoxItem = comboBox.ItemContainerGenerator.ContainerFromItem(comboBox.SelectedItem) as ComboBoxItem; if (comboBoxItem == null) { return; } TextBlock textBlock = FindVisualChildByName<TextBlock>(comboBoxItem, "nameTextBlock"); MessageBox.Show(textBlock.Text); } private static T FindVisualChildByName<T>(DependencyObject parent, string name) where T : DependencyObject { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) { var child = VisualTreeHelper.GetChild(parent, i); string controlName = child.GetValue(NameProperty) as string; if (controlName == name) { return child as T; } T result = FindVisualChildByName<T>(child, name); if (result != null) return result; } return null; } 抱歉来晚了一点 :) 但以下也有效(具有讽刺意味的是和你在同一个修复中!!) TextBlock tb1 = (TextBlock)cbo_team.SelectedItem; MessageBox.Show(tb1.Text); private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { ListBox ContactListBox = sender as ListBox; ListBoxItem listBoxItem = ContactListBox .ItemContainerGenerator.ContainerFromItem(ContactListBox.SelectedItem) as ListBoxItem; if (listBoxItem == null) { return; } TextBlock txtBlock = FindVisualChildByName<TextBlock>(listBoxItem, "ListTextBlock"); MessageBox.Show(txtBlock.Text); } private static T FindVisualChildByName<T>(DependencyObject parent, string name) where T : DependencyObject { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) { var child = VisualTreeHelper.GetChild(parent, i); string controlName = child.GetValue(NameProperty) as string; if (controlName == name) { return child as T; } T result = FindVisualChildByName<T>(child, name); if (result != null) return result; } return null; } 其他人已经建议使用 SelectionChanged 事件。没有测试下面的代码,但你可以试一试。 private void OnMyComboBoxChanged(object sender, SelectionChangedEventArgs e) { TextBlock tvContent = (sender as ComboBox).SelectedItem as TextBlock; string content = tvContent.Text; } private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { var comboBox = (ComboBox)sender; ComboBoxItem comboAsTextblock = (ComboBoxItem)comboBox.SelectedItem; string comboBoxItemText = comboAsTextblock.Content.ToString(); // comboBoxItemText is what you want :) }