Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用ObservableCollection绑定到ItemSource时出现列表框问题_C#_Wpf_Binding_Listbox - Fatal编程技术网

C# 使用ObservableCollection绑定到ItemSource时出现列表框问题

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"

绑定到列表框控件的ItemsSource时遇到问题。我希望能够在用户执行某些操作时向列表框添加文本行

SystemControls.xmal代码:

<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();
        }