首页 > 解决方案 > 如何将类字段绑定到自定义模板中的元素?(WPF)

问题描述

如何将类字段绑定到自定义 ListBoxItem 模板中的元素?此示例代码缺少类定义、ListBox 名称等某些方面,我只是在绑定过程中挣扎。

<ListBox>
    <ListBox.Resources>
        <Style TargetType="ListBoxItem">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>

                       <!-- how to bind class fields to these elements -->

                        <StackPanel Orientation="Horizontal">
                            <Label></Label>
                            <Image></Image>
                        </StackPanel>

                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.Resources>

    <!-- adding items dynamically -->

</ListBox>

C# 代码应如下所示:

ListBoxItem listBoxItem = new ListBoxItem();
listBoxItem.Content = new MyClass(){ Name="MyName", Image="ImagePath"}
... append to ListBox ... 

标签: c#wpfbinding

解决方案


在 WPF 中开发时,鼓励使用 MvvM 来促进关注点分离。为此,需要实现一个带有属性的视图模型,然后将其绑定到视图。当您希望 UI(视图)了解 View Model 提供的数据的更改时,必须实现INotifyPropertyChanged接口,如下所示:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows.Threading;    

namespace ViewModels
{
    public class BaseViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public BaseViewModel()
        {
             //ctor
        }

        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            UIThread( () =>
            {
                //make sure the event is raised on the main thread
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            });
        }

        Dispatcher _dispacther;

        protected void UIThread(Action action)
        {
            if (_dispacther == null)
            {
                _dispacther = Dispatcher.CurrentDispatcher;
            }
            _dispacther.Invoke(action);
        }
    }
}  

您的Hello类将派生自 BaseViewModel 并提供 OnPropertyChanged(); 在这样的属性中:

    private string name;

    public string Name
    {
        get { return name; }
        set { name= value; OnPropertyChanged(); }
    }

现在,当您更改 ListBox 中选定项目的名称时,它将反映在 UI 中。试试看!此实现确保事件在主线程上引发,因此在调用事件时不需要这样做。还将[CallerMemberName]填充您调用的属性的名称!


推荐阅读