C#WPF绑定到索引属性-我做错了什么
本文关键字:错了 什么 属性 绑定 索引 C#WPF | 更新日期: 2024-09-17 02:59:40
我最近发现了索引属性。这看起来是一个完美的解决方案,在这种情况下,我正在处理的数据最好在集合中表达,但仍需要实现为可在XAML数据绑定中使用的属性。我从创建索引属性的测试开始,在那里我没有遇到任何问题,但我似乎无法使绑定工作。
有人能指出我哪里错了吗?
下面是一个带有嵌套类的测试类,用于创建索引属性:
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事件并通过以下方式传播消息:
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();
}
}