C#WPF绑定到索引属性-我在做什么错? [英] C# WPF Binding to indexed property - what am I doing wrong?

查看:90
本文介绍了C#WPF绑定到索引属性-我在做什么错?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近发现了索引属性.对于正在处理的数据最好在集合中表示的情况,这似乎是一种完美的解决方案,但仍需要将其实现为可用于XAML数据绑定的属性.我从创建索引属性的测试开始,那里没有问题,但是似乎无法使绑定正常工作.

I have recently discovered indexed properties. This looks like the perfect solution to the scenario in which the data I am working with would best be expressed in a collection, yet still needs to be implemented as a property that can be used in XAML databinding. I started with just a test of creating indexed properties, and I had no problems there, but I just don't seem to be able to get the binding to work.

有人能指出我要去哪里了吗?

Can anyone point out where I'm going wrong?

这是带有嵌套类的测试类,用于创建索引属性:

Here is the test class with a nested class to create the indexed property:

public class TestListProperty 
{

    public readonly ListProperty ListData;

    //---------------------------
    public class ListProperty : INotifyPropertyChanged 
    {
        private List<string> m_data;

        internal ListProperty()
        {
            m_data = new List<string>();
        }

        public string this[int index]
        {
            get
            {
                if ( m_data.Count > index )
                {
                    return m_data[index]; 
                }
                else
                {
                    return "Element not set for " + index.ToString();
                }
            }
            set
            {
                if ( m_data.Count > index )
                {
                    m_data[index] = value;
                }
                else
                {
                    m_data.Insert( index, value );
                }
                OnPropertyChanged( "Item[]" );
                Console.WriteLine( value );
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged( string propertyName )
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if ( handler != null ) handler( this, new PropertyChangedEventArgs( propertyName ) );
        }

    }
    //---------------------------
    public TestListProperty()
    {
        ListData = new ListProperty();
    }

}

这是XAML:

<Window x:Class="TestIndexedProperties.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>

        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <TextBox Width="200" Grid.Row="0" Text="{Binding Path=ListData[0], Mode=TwoWay}" />
        <TextBox Width="200" Grid.Row="1" Text="{Binding Path=ListData[1], Mode=TwoWay}" />
        <TextBox Width="200" Grid.Row="2" Text="{Binding Path=ListData[2], Mode=TwoWay}" />


    </Grid>
</Window>

这是窗口代码:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        TestListProperty test = new TestListProperty();

        this.DataContext = test;

        test.ListData[0] = "ABC";
        test.ListData[1] = "Pleeez 2 wurk?";
        test.ListData[2] = "Oh well";

    }
}

感谢所有帮助!

推荐答案

您的代码中没有机制可以在列表更改时向前端指示,即ListProperty正在实现INotifyPropertyChanged而不是INotifyCollectionChanged.最简单的解决方法是将m_data更改为ObservableCollection类型,然后将您的XAML控件绑定到该类型,尽管这可能违背了您最初尝试执行的操作的目的.正确"的方法是订阅CollectionChanged事件并通过以下方式传播消息:

There's no mechanism in your code to indicate to the front-end when the list has changed, i.e. ListProperty is implementing INotifyPropertyChanged instead of INotifyCollectionChanged. The easiest fix would be to change m_data to type ObservableCollection and bind your XAML controls to that instead, although that probably defeats the purpose of what you're trying to do in the first place. The "proper" way is to subscribe to the CollectionChanged event and propagate the messages through:

public class TestListProperty
{
    public ListProperty ListData { get; private set; }

    //---------------------------
    public class ListProperty : INotifyCollectionChanged
    {
        private ObservableCollection<string> m_data;

        internal ListProperty()
        {
            m_data = new ObservableCollection<string>();
            m_data.CollectionChanged += (s, e) =>
            {
                if (CollectionChanged != null)
                    CollectionChanged(s, e);
            };
        }

        public string this[int index]
        {
            get
            {
                if (m_data.Count > index)
                {
                    return m_data[index];
                }
                else
                {
                    return "Element not set for " + index.ToString();
                }
            }
            set
            {
                if (m_data.Count > index)
                {
                    m_data[index] = value;
                }
                else
                {
                    m_data.Insert(index, value);
                }
                Console.WriteLine(value);
            }
        }

        public event NotifyCollectionChangedEventHandler CollectionChanged;

    }
    //---------------------------
    public TestListProperty()
    {
        ListData = new ListProperty();
    }
}

这篇关于C#WPF绑定到索引属性-我在做什么错?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆