C# 使用ObservableCollection绑定到ItemSource时出现列表框问题
绑定到列表框控件的ItemsSource时遇到问题。我希望能够在用户执行某些操作时向列表框添加文本行 SystemControls.xmal代码:C# 使用ObservableCollection绑定到ItemSource时出现列表框问题,c#,wpf,binding,listbox,C#,Wpf,Binding,Listbox,绑定到列表框控件的ItemsSource时遇到问题。我希望能够在用户执行某些操作时向列表框添加文本行 SystemControls.xmal代码: <ListBox Grid.Column="4" Grid.Row="1" Grid.RowSpan="9" ItemsSource="{Binding ListBoxInput}" Height="165" HorizontalAlignment="Left" Name="listBox1" VerticalAlignment="Top"
<ListBox Grid.Column="4" Grid.Row="1" Grid.RowSpan="9" ItemsSource="{Binding ListBoxInput}" Height="165" HorizontalAlignment="Left" Name="listBox1" VerticalAlignment="Top" Width="250" ></ListBox>
SystemControls_VM.cs这应该是问题的核心所在。我已经让它在构造函数中工作,当我稍后尝试在代码中添加行时,例如当用户按下按钮时,它什么也不做:
public class SystemControls_VM:ViewModelBase, ISystemControls_VM
{
IDriver _Driver;
public ObservableCollection<string> _ListBoxInput = new ObservableCollection<string>();
public SystemControls_VM(IDriver InDriver)
{
_Driver = InDriver;
ListBoxInput.Add("test");//Works here
}
public ObservableCollection<string> ListBoxInput
{
get
{
return _ListBoxInput;
}
set
{
_ListBoxInput = value;
//OnPropertyChanged("ListBoxInput");
}
}
public void OnButtonClickGetNextError()
{
ListBoxInput.Add("NextErrorClicked");//Does not work here
}
public void OnButtonClickClear()
{
ListBoxInput.Clear();//Or Here
}
公共类SystemControls\u VM:ViewModelBase、ISystemControls\u VM
{
司机(司机),;
公共ObservableCollection_ListBoxInput=新ObservableCollection();
公共系统控制\u VM(IDriver InDriver)
{
_司机=INDRIVE;
ListBoxInput.Add(“test”);//在这里工作
}
公共可观察收集ListBoxInput
{
得到
{
返回ListBoxInput;
}
设置
{
_ListBoxInput=值;
//OnPropertyChanged(“ListBoxInput”);
}
}
public void OnButtonClickGetNextError()
{
ListBoxInput.Add(“NextErrorClicked”);//在此处不起作用
}
公共无效OnButtonClickClear()
{
ListBoxInput.Clear();//或此处
}
此外,如果需要OnPropertyChangedEventHandler:
namespace XXX.BaseClasses.BaseViewModels
{
/// <summary>
/// Provides common functionality for ViewModel classes
/// </summary>
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate{};
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
namespace XXX.BaseClasses.BaseViewModels
{
///
///为ViewModel类提供通用功能
///
公共抽象类ViewModelBase:INotifyPropertyChanged
{
公共事件PropertyChangedEventHandler PropertyChanged=委托{};
受保护的无效OnPropertyChanged(字符串propertyName)
{
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
}
1)您的公共属性被称为\u ListBoxInput,但您绑定到ListBoxInput(无下划线)。请将\u ListBoxInput设为私有
2) 因为集合已经是可观察的,所以更新列表框时不需要OnPropertyChanged
3) 您管理公共与私有ListBoxInput集合的方式似乎有问题。您正在调用.Add on您的公共属性(这将立即引发可观察集合上的事件)但是,您最终也会将其添加到私有集合中,然后在公共属性上调用PropertyChanged。这令人困惑:请尝试下面的代码,看看它是如何工作的。(注意,在构造函数中,您将其添加到了_ListBoxInput,但在按钮单击事件中,您将其添加到了ListBoxInput。)
4) 尝试在构造函数中添加this.DataContext=this
public partial class MainWindow : Window {
public ObservableCollection<string> ListBoxInput { get; private set; }
public MainWindow() {
InitializeComponent();
this.ListBoxInput = new ObservableCollection<string>();
this.DataContext = this;
}
private void AddListBoxEntry_Click(object sender, RoutedEventArgs e) {
this.ListBoxInput.Add("Hello " + DateTime.Now.ToString());
}
}
所以我从另一个来源得到了答案,但我想我会把它贴在这里作为参考
所以发生的事情是,我正在将数据上下文设置为SystemControls_VM的一个实例,而处理按钮单击的我的_VM引用将转到SystemControls_VM的另一个实例。这也是为什么看起来按钮单击正在工作,列表正在填充,但没有数据到达它所在的控件自我
我更改了代码的以下部分,它可以正常工作:
public partial class SystemControls : UserControl, ISystemControls
{
IDriver _Driver;
SystemControls_VM _VM;
public SystemControls(IDriver InDriver, SystemControls_VM InVM)
{
_VM = InVM;
_Driver = InDriver;
DataContext = InVM;//new SystemControls_VM(_Driver);
InitializeComponent();
}
您是否检查了OnButtonClickGetNextError方法是否实际被调用?尝试在其中放置断点。是的,首先尝试了该方法。它被调用,并且_ListBoxInput显示其中包含其他项,但是Listbox本身从未使用新项进行更新。向Listbox ItemsSource添加模式=单向。问题仍然存在ges将_ListBoxInput的实例设置为ListBoxInput。问题仍然存在。请尝试设置datacontext。如果这不起作用,请从新项目中的示例代码开始,确认它起作用,然后再继续。不起作用datacontext已设置为SystemControls_VM。我遇到的问题很可能与发送的消息和通知有关这个上下文(我假设我没有处理一个我应该处理的上下文,只是不知道它是什么。)。我已经让它在SystemControls.xaml.cs文件内部工作,但我需要的是让它在引用的DataContext中工作。我已经更新了原始问题,以更清楚地说明每段代码的来源。
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<ListBox ItemsSource="{Binding ListBoxInput, Mode=OneWay}"
Height="165" HorizontalAlignment="Left"
Name="listBox1" VerticalAlignment="Top" Width="250" />
<Button Grid.Column="1" Grid.Row="0" Name="AddListBoxEntry"
Margin="0,0,0,158" Click="AddListBoxEntry_Click" >
<TextBlock>Add</TextBlock>
</Button>
</Grid>
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate{};
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public partial class SystemControls : UserControl, ISystemControls
{
IDriver _Driver;
SystemControls_VM _VM;
public SystemControls(IDriver InDriver, SystemControls_VM InVM)
{
_VM = InVM;
_Driver = InDriver;
DataContext = InVM;//new SystemControls_VM(_Driver);
InitializeComponent();
}