数据绑定到另一个 Collection 中的 Collection 中的 属性

Data Binding to a Property within a Collection in another Collection

我在数据绑定到 属性 时遇到问题,该 属性 在 collection 中有两层深度。

object 的结构是这样的 Collection - 数据 - 名称 --Collection - 名称 --数据

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

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();
        }
    }

在此先感谢您的帮助。

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

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

到(如果你想在图形中显示所有名称)

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

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

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

将解决问题。