WPF。将列表框 itemtemplate 内部绑定到 ObservableCollection 源。源 PropertyChanged 被忽略

2023-12-06

我正在尝试创建一个显示格式化文本的列表框。我希望能够更改代码的格式。

为了显示格式化文本,我选择了 TextBlock 并打算使用 TextBlock.Inlines 集合进行格式化。 TextBlock.Inlines 不可绑定,所以我创建了新类可绑定文本块派生自 TextBlock。该类有一个依赖属性内联列表我试图绑定到内联科尔模型中的 ObservableCollection。

问题是变化内联科尔不要通知我的内联列表关于 PropertyChanged 事件。绑定仅在以下时间起作用一次可绑定文本块对象创建时间及其之后。

有什么想法吗?

XAML:

                <ListBox  x:Name="PART_lb" VerticalAlignment="Stretch" ItemsSource="{Binding ItemColl}"
                            ScrollViewer.HorizontalScrollBarVisibility="Auto" 
                            ScrollViewer.VerticalScrollBarVisibility="Auto" >
                    
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <local:BindableTextBlock InlineList="{Binding Path=InlinesColl}" />
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                    
                </ListBox>

BindableTextBlock 类:

 public class BindableTextBlock : TextBlock
    {
        public ObservableCollection<Inline> InlineList
        {
            get { return (ObservableCollection<Inline>)GetValue(InlineListProperty); }
            set { SetValue(InlineListProperty, value); }
        }

        public static readonly DependencyProperty InlineListProperty =
            DependencyProperty.Register("InlineList", typeof(ObservableCollection<Inline>), typeof(BindableTextBlock), new UIPropertyMetadata(null, OnPropertyChanged));

        private static void OnPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            BindableTextBlock textBlock = (BindableTextBlock)sender;
            textBlock.Inlines.Clear();
            textBlock.Inlines.AddRange((ObservableCollection<Inline>)e.NewValue);
        }

      
    }

模型类

    public class TextBlockModel
    {

        ObservableCollection<Inline> _inlinesColl = new ObservableCollection<Inline>();
        public ObservableCollection<Inline> InlinesColl
        {
            get { return _inlinesColl; }
            set {_inlinesColl = value; }
        }
    }

带有 ListBox ItemSsource 集合的 ViewModel

        ObservableCollection<TextBlockModel> _itemColl = new ObservableCollection<TextBlockModel>();
        public ObservableCollection<TextBlockModel> ItemColl
        {
            get { return _itemColl; }
            set { _itemColl = value; }
        }

测试项目here


在您的情况下 - 当集合内的项目添加\删除时,您没有处理案例
当新的集合被分配时,需要深度订阅CollectionChanged。

 public class BindableTextBlock : TextBlock
    {
        static int Cntr = 0;
        public BindableTextBlock()
        {
            Console.WriteLine("BindableTextBlock constructor " + Cntr);
            Cntr++;
        }

        public ObservableCollection<Inline> InlineList
        {
            get { return (ObservableCollection<Inline>)GetValue(InlineListProperty); }
            set { SetValue(InlineListProperty, value); }
        }

        public static readonly DependencyProperty InlineListProperty =
            DependencyProperty.Register("InlineList", typeof(ObservableCollection<Inline>), typeof(BindableTextBlock), new UIPropertyMetadata(null, OnPropertyChanged));

        private static void OnPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            BindableTextBlock textBlock = (BindableTextBlock)sender;

            // subscribe to collection changed
            textBlock.UpdateInlineListSource((ObservableCollection < Inline > )e.OldValue, (ObservableCollection < Inline > )e.NewValue);

        }

        public void UpdateInlineListSource(ObservableCollection<Inline> oldCollection, ObservableCollection<Inline> newCollection)
        {
            if (oldCollection!=null)
            oldCollection.CollectionChanged -= OnCollectionChanged;

            if (newCollection != null)
            {
                newCollection.CollectionChanged += OnCollectionChanged;
                OnCollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
                OnCollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, newCollection));
            }
        }

        private void OnCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            var newItems = e.NewItems?.Cast<Inline>()?.ToList() ?? new List<Inline>();
            var oldItems = e.OldItems?.Cast<Inline>()?.ToList() ?? new List<Inline>();

            // changed source
            if (e.Action==NotifyCollectionChangedAction.Reset)
                this.Inlines.Clear();

            foreach (var itemForDelete in oldItems)
            {
                if (this.Inlines.Contains(itemForDelete))
                    this.Inlines.Remove(itemForDelete);
            }

            foreach (var itemsForAdd in newItems)
            {
                this.Inlines.Add(itemsForAdd);
            }
        }
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WPF。将列表框 itemtemplate 内部绑定到 ObservableCollection 源。源 PropertyChanged 被忽略 的相关文章

  • dup2() 和 exec()

    include
  • 如何将不记名令牌发送到 ASP NET MVC 5 中的视图?

    我有一个 NET MVC and WEB API项目 我想打电话给WEB API controllers来自 javascript 但我没有找到将令牌发送到我的视图的方法 我想添加bearer token in Viewbag变量 使用以下
  • binary_log_types.h:没有这样的文件或目录

    我正在编译一个小型 mysql C 项目并且 遇到以下错误 C Program Files x86 MySQL MySQL Server 5 7 include mysql com h 22 30 fatal error binary lo
  • 可变数量的(常量)引用参数

    我试图从我的高级代码 使用 C 11 中消除原始指针 并且我找到了引用 尤其是const 在许多情况下 当没有所有权转移时 是一个很好的替代品 但如果有的话该怎么办variable我想通过 常量 引用传递的参数数量 你不能创建一个std v
  • 将 void *user_data 转换为对象

    我该如何投射void something到标准 C 中的对象 具体来说我想投void userdata to std map
  • 比较 LINQ to SQL 中的两个日期

    我有一个数据库 其中有一个名为会议的表 会议日期使用以下格式存储在此表中 May 2nd 2011 例如 格式为5 2 2011 我的要求是获取两个日期 例如 2011 年 4 月 25 日和 2011 年 5 月 2 日 之间的会议 并编
  • 计算复杂数组的abs()值的最快方法

    我想计算 C 或 C 中复杂数组元素的绝对值 最简单的方法是 for int i 0 i lt N i b i cabs a i 但对于大向量来说 速度会很慢 有没有办法加快速度 例如使用并行化 语言可以是 C 或 C 鉴于所有循环迭代都是
  • 在目标 VS 安装时,VSIX 扩展内部使用的 WPF-Log4Net 未输出日志

    当 Log4net 在 VSIX 扩展中使用并安装在另一个目标 VS 上时 它不会记录日志 我有一个 WPF 解决方案 我下载了 log4net dll 添加了 log4net config 并将 复制到输出目录 值设置为 始终复制 log
  • std::tr1::function 和 std::tr1::bind

    我在使用时遇到问题veryC 类中的复杂 C 函数 重写 C 函数是not一个选项 C函数 typedef void integrand unsigned ndim const double x void fdata unsigned fd
  • 我的 WPF 应用程序未触发 MainWindow_Loaded

    我目前正在关注Pluralsight C Fundamentals Part 1并在Classes and Objects视频部分指导我在 Visual Studio 中创建一个新的 WPF 应用程序并填写代码 这导致以下结果 namesp
  • boost::asio::io_service 是否保留处理程序的顺序?

    Does boost asio io service http www boost org doc libs release doc html boost asio reference io service html保证处理程序的调用顺序与
  • 如何在Azure功能中添加razor视图文件?

    我正在创建一个应用程序 它是 azure 函数项目 我想在该项目中使用 Razor 视图 我应该在 azure 函数中使用任何模板引擎吗 得益于一些方面的进步剃刀之光项目 https github com toddams RazorLigh
  • ASP.NET中如何访问除wwwroot以外的位置

    我可以使用访问服务器的物理位置Server MapPath 这给了我内部的物理路径wwwroot文件夹 我想将一些数据保存到同一服务器的另一个驱动器中D 驾驶 我想我无法获取以下位置的物理位置D 驾驶使用Server MapPath因为它位
  • 为什么这个单独的定义会导致错误?

    挑战 我有这段代码无法编译 你能找出问题所在吗 有一次让我很头疼 header namespace values extern std string address extern int port cpp file std string v
  • 为什么必须通过 this 指针访问模板基类成员?

    如果下面的类不是模板 我可以简单地拥有x in the derived班级 但是 通过下面的代码 我have to use this gt x Why template
  • 生成范围 [min,max] 内的随机数 [重复]

    这个问题在这里已经有答案了 我正在使用 C 生成范围 min max 内的整数随机数 我在用 int random int int min int max return min rand max min 但我认为上面的代码适用于范围 min
  • 使用 _Alignas 进行结构成员对齐

    我想知道以下问题 是新的吗 Alignas结盟 C11 中的说明符适用于结构成员吗 我一直假设这么多 但彻底阅读了 N1570 公开草案似乎表明对齐说明符不能 出现在一个说明符限定符列表 这就是我所期望的 如果得到支持的话 我已经读过几遍语
  • 将多个 Blob 输入传递到 QueueTrigger Azure 函数的最佳方法

    问题 触发后 生成 3 个 XML 文件 完成后将它们通过 ftp 传输到站点 目前的方法 我有一个 HTTP 触发器 Azure 函数 运行时将构造 3 个 XML 文件并将它们保存到 Azure 存储 Blob 容器中 由于有多个输出
  • “显式”关键字对返回值优化 (RVO) 有何影响?

    以下代码工作得很好 显示 RVO struct A A int cout lt lt A A n constructor A const A cout lt lt A A const A n copy constructor A foo r
  • DataGridView 捕获用户行选择

    我在处理选择时遇到问题DataGridView 我的网格视图包含一个金额列 表单上有一个文本框 应显示所选网格视图行的总数 因此 我需要在用户选择 取消选择 gridview 行时捕获事件并相应地计算 添加 减去 金额 我找到了两种方法 使

随机推荐