【问题标题】:Data Binding to a Property within a Collection in another Collection数据绑定到另一个集合中的集合中的属性
【发布时间】:2022-01-10 08:49:29
【问题描述】:

我在将数据绑定到集合中的两层深度的属性时遇到问题。

对象的结构是这样的 收藏 - 数据 - 姓名 - 收藏 - 姓名 --数据

所以本质上它是集合中的集合,我似乎无法绑定到包含集合中的名称。 我可以绑定到初始集合的所有属性,包括其中的集合,但是一旦我尝试绑定到内部集合的 name 属性,我就会得到错误的绑定。

XAML 部分

<TabControl ItemsSource="{Binding Path=BMOverlayCollection}" Grid.Column="0" Grid.Row="4" Grid.ColumnSpan="4">
            <TabControl.ItemTemplate>
                <!-- this is the header template-->
                <DataTemplate>
                    <TextBlock
                Text="{Binding Name}" />
                </DataTemplate>
            </TabControl.ItemTemplate>
            <TabControl.ContentTemplate>
                <!-- this is the body of the TabItem template-->
                <DataTemplate>
                    <TextBlock
                Text="{Binding Graphics.Name}" />
                </DataTemplate>
            </TabControl.ContentTemplate>
        </TabControl>

C#部分

    public class BMGraphicsOverlayCollection : INotifyPropertyChanged, IEnumerable
    {
    #region Event Property
    public event PropertyChangedEventHandler? PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion

        private ObservableCollection<NamedOverlay> _namedOverlays;
        public ObservableCollection<NamedOverlay> NamedOverlays { get { return _namedOverlays; } set { _namedOverlays = value; OnPropertyChanged(); } }

        public BMGraphicsOverlayCollection()
        {
            _namedOverlays = new ObservableCollection<NamedOverlay>(); 
        }
        public void Add(string name, GraphicsOverlay overlay)
        {
            NamedOverlay mOverlay = new NamedOverlay();
            mOverlay.Name = name;
            mOverlay.Overlay = overlay;
            _namedOverlays.Add(mOverlay);
        }

        public void Add(string name, GraphicsOverlay overlay, IList<MapGraphic> graphics)
        {
            NamedOverlay mOverlay = new NamedOverlay();
            mOverlay.Name = name;
            mOverlay.Overlay = overlay;
            mOverlay.Graphics = new ObservableCollection<MapGraphic>(graphics);
            _namedOverlays.Add(mOverlay);
        }

        public IEnumerator GetEnumerator()
        {
            return _namedOverlays.GetEnumerator();
        }
    }
    public class NamedOverlay : INotifyPropertyChanged
    {
        #region Event Property
        public event PropertyChangedEventHandler? PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
        private string _name;
        public string Name { get { return _name; } set { _name = value; OnPropertyChanged(); } }
        private GraphicsOverlay _overlay;
        public GraphicsOverlay Overlay { get { return _overlay; } set { _overlay = value; OnPropertyChanged(); } }
        private ObservableCollection<MapGraphic> _graphics;
        public ObservableCollection<MapGraphic> Graphics { get { return _graphics; } set { _graphics = value; OnPropertyChanged(); } }
    }

}

还有MapGraphic相关部分

        private string _name;
    public string Name
    {
        get
        {
            if (_name == null)
            {
                return "Unnamed";
            } else
            {
                return _name;
            }
        }
        set
        {
            _name = value; OnPropertyChanged();
        }
    }

提前感谢您的帮助。

【问题讨论】:

  • 我没有测试过,但是你的绑定是 xaml 中的Path=BMOverlayCollection,它似乎没有出现在其他任何地方。还是就是上面那个级别(Collection)?
  • 该路径有效,由于它无关紧要,我省略了它的代码。
  • 好的,您能否为 BMOverlayCollection 类添加代码。我会帮助更好地理解绑定元素的结构。
  • 该课程的代码在那里,它是我帖子的第二个部分。你指的是实例化类的代码吗?就像我说的,绑定钩子很好,我什至可以绑定到“图形”属性(不过,当我这样做时,它显示为简单的(集合)。当我尝试绑定到图形中的属性“名称”时)属性,那就是绑定失败的时候。

标签: c# wpf xaml data-binding


【解决方案1】:

根据您的代码,您的数据结构是 NamedOverlays[].Graphics[].Name,但您的绑定路径是 NamedOverlays[].Graphics.Name。这就是绑定不好的原因。改变

<TextBlock Text="{Binding Graphics.Name}" />

to(如果您想在 Graphics 中显示所有名称)

<ListBox ItemsSource="{Binding Graphics}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Name}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

或(如果您只想在图形中显示第一个名字)

<TextBlock Text="{Binding Graphics[0].Name}" />

将解决问题。

【讨论】:

  • 这是有道理的。我之前曾尝试过类似的操作,但没有成功,我相信是因为我没有使用其他数据模板。非常感谢您的帮助!
最近更新 更多