【问题标题】:Access the TextBlock 's text at run time in DataTemplate of ItemsControl in WPF运行时在 WPF 中 ItemsControl 的 DataTemplate 中访问 TextBlock 的文本
【发布时间】:2014-05-01 17:17:18
【问题描述】:

我正在我的 WPF 应用程序中显示消息
当新消息添加到消息中时,我需要突出显示它。所以我想动态获取添加到 TextBlock 的文本

我有这样的xaml

 <ItemsControl Name="DialogItemsControl" ItemsSource="{Binding Messages, Mode=OneWay}" Background="Transparent" 
                          BorderBrush="Transparent" TargetUpdated="DialogItemsControl_TargetUpdated">
                <ItemsControl.ItemTemplate><!-- For ever message -->
                    <DataTemplate>
                        <Grid Margin="0,0,0,20">
                            <ItemsControl Name="SubDialogItemsControl"
                                  Foreground="{DynamicResource ButtonTextBrush}" 
                                  ItemsSource="{Binding Lines,NotifyOnTargetUpdated=True}"
                                  Margin="0,0,0,12"
                                  Grid.Column="0">
                                <ItemsControl.ItemTemplate><!-- For every line -->
                                    <DataTemplate>
                                        <TextBlock Name="DialogMessageText" 
                                                   Text="{Binding NotifyOnTargetUpdated=True}" 
                                            VerticalAlignment="Top" 
                                            Margin="0,2,0,2" 
                                            TextTrimming="WordEllipsis"/>
                                    </DataTemplate>
                                </ItemsControl.ItemTemplate>                                    
                            </ItemsControl>
                        </Grid>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>

代码隐藏类中的代码是这样的:

private void DialogItemsControl_TargetUpdated(object sender, System.Windows.Data.DataTransferEventArgs e)
        {  
          ItemsControl itemControl = sender as ItemsControl;

            ContentPresenter dp =   itemControl.ItemContainerGenerator.ContainerFromItem(itemControl.Items.CurrentItem) as ContentPresenter;

            // Finding textBlock from the DataTemplate that is set on that ContentPresenter
            DataTemplate myDataTemplate = dp.ContentTemplate;
            ItemsControl itc = (ItemsControl)myDataTemplate.FindName("SubDialogItemsControl", dp);
            if (itc != null && itc.ItemContainerGenerator.Status == System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
            {
                ContentPresenter cp = itc.ItemContainerGenerator.ContainerFromIndex(0) as ContentPresenter;
                DataTemplate dt = cp.ContentTemplate;
                TextBlock tb = dt.LoadContent() as TextBlock;               

                tb.TargetUpdated += new EventHandler<System.Windows.Data.DataTransferEventArgs>(myTextBlock_TargetUpdated);
            }            
        }

 void myTextBlock_TargetUpdated(object sender, System.Windows.Data.DataTransferEventArgs e)

       {

            TextBlock tb = sender as TextBlock;
           //When i access the text property of tb, its showing null, how to get the text
        }

当我在文本块的目标更新事件中访问文本块的文本属性时,它显示为空,如何读取文本。

提前致谢

【问题讨论】:

    标签: wpf time datatemplate textblock


    【解决方案1】:

    您从错误的角度解决了问题(并且可能在此过程中添加了内存泄漏,因为我没有看到您取消订阅该事件)。

    您需要创建一个自定义 TextBlock,覆盖 Text 属性的元数据,以便在文本字符串更改时(通过 PropertyChangedCallback)更改背景几秒钟。

    然后在 ItemsControl 的 DataTemplate 中使用该自定义 TextBlock。

    编辑 - 我认为其他人可能需要此功能,所以这是一个工作示例:

    public class CustomTextBlock : TextBlock
        {
            static CustomTextBlock()
            {
                TextProperty.OverrideMetadata(typeof(CustomTextBlock), new FrameworkPropertyMetadata(null, 
                    new PropertyChangedCallback(
                        (dpo, dpce) => 
                        {
                            //Flash the background to yellow for 2 seconds
                            var myTxtblk = dpo as CustomTextBlock;
                            if (myTxtblk != null)
                            {
                                myTxtblk.Background = Brushes.Yellow;
                                Task.Factory.StartNew(
                                    () => 
                                    {
                                        Thread.Sleep(2000);
                                        Application.Current.Dispatcher.Invoke(
                                            new Action(() => 
                                            {
                                                myTxtblk.Background = Brushes.Transparent;
                                            }));
                                    });
                            }
                        })));
            }
        }
    

    然后你需要在你的 XAML 视图中声明正确的 xmlns 命名空间,并像使用常规 TextBlock 一样使用它:

    <local:CustomTextBlock Text="{Binding MyDynamicText}"/>
    

    修改 MyDynamicText 时它会闪烁黄色(前提是它引发 PropertyChanged)。

    【讨论】:

      猜你喜欢
      • 2017-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-12
      • 2011-03-09
      • 1970-01-01
      • 1970-01-01
      • 2011-04-23
      相关资源
      最近更新 更多