WPF xaml自定义绑定标记

9 篇文章 0 订阅

当需要在xaml中绑定至数组中的某个元素时,常规写法不利于阅读理解,因为你必须得知道这个元素在集合中的位置才能进行绑定。下面以班级中学生的名字为例:
比如我想绑定至A班学号为1的学生的名字
常规写法:(前提是你得知道这个学生在集合中的第一个位置)

<TextBlock Text="{Binding Path=(local:Students.StuClassList)[0].StudentList[0].Name}" Width="100" Height="30"/>

想用自定义写法实现:

<TextBlock Text="{ local:StudentBinding A.1.Name}" Width="100" Height="30"/>

班级类:

    public class StuClass : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private string _classId;
        public string ClassID
        {
            get { return _classId; }
            set
            {
                _classId = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("ClassID"));
            }
        }

        private ObservableCollection<Student> _studentList = new ObservableCollection<Student>();

        public ObservableCollection<Student> StudentList
        {
            get { return _studentList; }
            set { _studentList = value; 
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("StudentList"));
            }
        }
    }

学生类:

   public static class Students
    {

        public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged;

        private static ObservableCollection<Student> _student = new ObservableCollection<Student>();
        public static ObservableCollection<Student> StudentList
        {
            get { return _student; }
            set
            {
                _student = value;
                StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs("StudentList"));
            }
        }
        private static ObservableCollection<StuClass> _stuClassesList = new ObservableCollection<StuClass>();

        public static ObservableCollection<StuClass> StuClassList
        {
            get { return _stuClassesList; }
            set { _stuClassesList = value; 
                StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs("StuClassList"));
            }
        }
    }

静态全局班级集合:

public static class Students
    {
        public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged;
        private static ObservableCollection<StuClass> _stuClassesList = new ObservableCollection<StuClass>();

        public static ObservableCollection<StuClass> StuClassList
        {
            get { return _stuClassesList; }
            set
            {
                _stuClassesList = value;
                StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs("StuClassList"));
            }
        }
    }

自定义绑定标记:

public class StudentBinding : MarkupExtension
    {
        public string Path;
        public StudentBinding()
        {
            
        }
        public StudentBinding(string path)
        {
            Path = path;
        }
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
                var result = Path.Split('.');
                StuClass stuclass = Students.StuClassList.Single(s => s.ClassID == result[0]) as StuClass;
                Student stu = stuclass.StudentList.Single(s => s.ID == int.Parse(result[1])) as Student;
                Binding binding = new Binding();
                binding.Source = stu;
                binding.Path = new PropertyPath(result[2]);
                binding.Mode = BindingMode.TwoWay;
                binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                binding.NotifyOnSourceUpdated = true;
                binding.NotifyOnTargetUpdated = true;
                return binding.ProvideValue(serviceProvider);
        }
    }

在窗体构造函数中添加班级和学生:

 public MainWindow()
        {
            StuClass stuClass = new StuClass();
            stuClass.ClassID = "A";
            stuClass.StudentList.Add(new Student()
            {
                ID = 1,
                Name = "可莉"
            });
            stuClass.StudentList.Add(new Student()
            {
                ID = 2,
                Name = "派蒙"
            });
            stuClass.StudentList.Add(new Student()
            {
                ID = 3,
                Name = "七七"
            });
            stuClass.StudentList.Add(new Student()
            {
                ID = 4,
                Name = "早柚"
            });
            Students.StuClassList.Add(stuClass);
            InitializeComponent();
        }

xaml:

<Grid>
        <StackPanel VerticalAlignment="Center">
            <TextBox Text="{ local:StudentBinding A.1.Name}" Width="100" Height="30"/>
            <TextBlock Text="{ local:StudentBinding A.2.Name}" Width="100" Height="30"/>
            <TextBlock Text="{Binding Path=(local:Students.StuClassList)[0].StudentList[0].Name}" Width="100" Height="30"/>
            <Button Content="change" Width="60" Height="30" Click="Button_Click"/>
        </StackPanel>
    </Grid>

效果:
在这里插入图片描述
属性变动通知测试:
前台改变数据:
在这里插入图片描述
后台改变数据:

private void Button_Click(object sender, RoutedEventArgs e)
        {
            Students.StuClassList[0].StudentList[0].Name = "宵宫";
        }

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值