Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.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# 从UI对ObservableCollection的更改未更新绑定集合_C#_Wpf_Xaml_Mvvm - Fatal编程技术网

C# 从UI对ObservableCollection的更改未更新绑定集合

C# 从UI对ObservableCollection的更改未更新绑定集合,c#,wpf,xaml,mvvm,C#,Wpf,Xaml,Mvvm,在XAML中,我有一个列表视图: <UserControl x:Class="HspSetup.View.UserInputData" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://sc

在XAML中,我有一个列表视图:

<UserControl x:Class="HspSetup.View.UserInputData"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:HspSetup.View"
             xmlns:viewModel="clr-namespace:HspSetup.ViewModel"
             xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
             xmlns:Behaviours="clr-namespace:HspSetup.Behaviours"
             mc:Ignorable="d" 
             Height="Auto" Width="Auto">
    <UserControl.Resources>
        <viewModel:UserInputDataViewModel x:Key="ViewModel"/>
    </UserControl.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="0.1*"/>       
            <RowDefinition Height="Auto"/>      
            <RowDefinition Height="*"/>       
            <RowDefinition Height="*"/>    
            <RowDefinition Height="*"/>       
            <RowDefinition Height="*"/>      
            <RowDefinition Height="*"/>     
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="0.5*"   />
            <ColumnDefinition Width="20*"/>
            <ColumnDefinition Width="0.5*" />
        </Grid.ColumnDefinitions>

        <TextBlock  Background="Coral" Height="50"
                    VerticalAlignment="Center" TextAlignment="Center"
                    Grid.Row="0"  Grid.ColumnSpan="3">
            <TextBlock.Text>Some More Data</TextBlock.Text>
            <TextBlock.FontFamily>Segoe UI</TextBlock.FontFamily>
            <TextBlock.Foreground>White</TextBlock.Foreground>
            <TextBlock.FontSize>30</TextBlock.FontSize>
        </TextBlock>

        <ListView   Grid.Row="2" Width="Auto" 
                    Behaviours:GridViewColumnResize.Enabled="True"
                    Height="Auto" Name="OrderNumberListView" 
                    IsSynchronizedWithCurrentItem="True" Grid.Column="1"
                    DataContext="{Binding Source={StaticResource ViewModel}}" 
                    ItemsSource="{Binding ConfigObjects}" >
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="HorizontalContentAlignment" 
                            Value="Stretch" />
                    <Setter Property="Behaviours:LostFocus.LostFocusCommand"
                            Value="{Binding Path=LostFocusCommand, Source={StaticResource ViewModel}}"/>
                    <Setter Property="Behaviours:LostFocus.CommandParem" 
                            Value="{Binding}"/>
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.View>
                <GridView>

                    <GridViewColumn Header="Order Name" 
                                    Behaviours:GridViewColumnResize.Width="*">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBox Text="{Binding OrderNumber, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                                         Style="{StaticResource flatTextBox}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Header="Type Name"
                                    Behaviours:GridViewColumnResize.Width="*">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBox Text="{Binding TypeName, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                                         Style="{StaticResource flatTextBox}">
                                </TextBox>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Behaviours:GridViewColumnResize.Width="*"  >
                        <GridViewColumn.HeaderTemplate>
                            <DataTemplate>
                                <Button Content="Add" 
                                        Command="{Binding AddConfigObjectCommand, Mode=OneWay, Source={StaticResource ViewModel}}"/>
                            </DataTemplate>
                        </GridViewColumn.HeaderTemplate>
                        <GridViewColumnHeader HorizontalContentAlignment="Stretch"/>
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <Button Name="RemoveButton" 
                                        Content="Remove" 
                                        Command="{Binding RemoveConfigObjectCommand, Mode=OneWay, Source={StaticResource ViewModel}}" CommandParameter="{Binding}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>
        </ListView>

    </Grid>
</UserControl>

更多数据
微软雅黑效果
白色
30
相应的UI如下所示:

单击“添加”按钮后,我添加一个空行,如下所示:

我在文本框中输入文本。 通过在文本框中输入文本对listview所做的更改不会更新文本框绑定到的observableCollection

可观测集合的类别如下所示:

class UserInputDataViewModel: BaseViewModel
{       
    private ObservableCollection<ConfigObject> _configObjects;

    public ObservableCollection<ConfigObject> ConfigObjects
    {
        get { return _configObjects; }
        set
        {
            _configObjects = value;
            OnPropertyChanged("ConfigObjects");
        }
    }

    private ICommand _addConfigObject;

    public ICommand AddConfigObjectCommand
    {
        get
        {
            if (_addConfigObject == null)
            {
                _addConfigObject = new RelayCommand(
                    p => AddConfigObject(),
                    p => CanAddConfigObject);
            }
            return _addConfigObject;
        }
    }

    private void AddConfigObject()
    {
        ConfigObjects.Add(new ConfigObject() { OrderNumber = "", TypeName = "" });
        OnPropertyChanged("ConfigObjects");
    }

    private ICommand _removeConfigObject;

    public ICommand RemoveConfigObjectCommand
    {
        get
        {
            if (_removeConfigObject == null)
            {
                _removeConfigObject = new RelayCommand(
                    p => RemoveConfigObject((ConfigObject)p),
                    p => CanRemoveConfigObject);
            }
            return _removeConfigObject;
        }
    }

    private void RemoveConfigObject(ConfigObject configObject)
    {
        ConfigObjects.Remove(configObject);
        OnPropertyChanged("ConfigObjects");
    }

    bool CanAddConfigObject
    {
        get { return true; }
    }
    bool CanRemoveConfigObject
    {
        get { return true; }
    }
}

class BaseViewModel:INotifyPropertyChanged
{
    /// <summary>
    /// Name of the property that changed
    /// </summary>
    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>
    /// Send the notification to the property that change
    /// </summary>
    /// <param name="pPropertyName">name of the property</param>
    protected virtual void OnPropertyChanged(string pPropertyName)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, 
                                 new PropertyChangedEventArgs(pPropertyName));
        }
    }
}

internal class ConfigObject : INotifyPropertyChanged
{
    private string _orderNumber;

    public string OrderNumber
    {
        get { return _orderNumber; }
        set { _orderNumber = value; OnPropertyChanged("OrderNumber"); }
    }

    private string _typeName;


    public string TypeName
    {
        get { return _typeName; }
        set { _typeName = value; OnPropertyChanged("TypeName"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string paramname)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(paramname));
    }
}
类UserInputDataViewModel:BaseViewModel { 私有ObservableCollection\u配置对象; 公共ObservableCollection配置对象 { 获取{return\u configObjects;} 设置 { _配置对象=值; OnPropertyChanged(“配置对象”); } } 私有ICommand_addConfigObject; 公共ICommand AddConfigObjectCommand { 得到 { 如果(_addConfigObject==null) { _addConfigObject=new RelayCommand( p=>AddConfigObject(), p=>CanadConfigObject); } 返回_addConfigObject; } } 私有void AddConfigObject() { 添加(新的ConfigObject(){OrderNumber=“”,TypeName=“”}); OnPropertyChanged(“配置对象”); } 私有ICommand_removeConfigObject; 公共ICommand RemoveConfigObjectCommand { 得到 { 如果(_removeConfigObject==null) { _removeConfigObject=新的RelayCommand( p=>RemoveConfigObject((ConfigObject)p), p=>CanRemoveConfigObject); } 返回removeConfigObject; } } 私有void RemoveConfigObject(ConfigObject ConfigObject) { ConfigObjects.Remove(configObject); OnPropertyChanged(“配置对象”); } 布尔CanAddConfigObject { 获取{return true;} } 布尔CanRemoveConfigObject { 获取{return true;} } } 类BaseViewModel:INotifyPropertyChanged { /// ///更改的属性的名称 /// 公共事件属性更改事件处理程序属性更改; /// ///向更改的属性发送通知 /// ///物业名称 受保护的虚拟void OnPropertyChanged(字符串PPPropertyName) { if(this.PropertyChanged!=null) { 这个。财产改变了(这个, 新属性ChangedEventArgs(PPPropertyName)); } } } 内部类ConfigObject:INotifyPropertyChanged { 私有字符串_orderNumber; 公共字符串顺序号 { 获取{return\u orderNumber;} 设置{u orderNumber=value;OnPropertyChanged(“orderNumber”);} } 私有字符串_typeName; 公共字符串类型名 { 获取{return\u typeName;} set{u typeName=value;OnPropertyChanged(“typeName”);} } 公共事件属性更改事件处理程序属性更改; 私有void OnPropertyChanged(字符串参数名) { if(PropertyChanged!=null) PropertyChanged(这是新的PropertyChangedEventArgs(paramname)); } }
通过编辑文本框中的文本,您不会更改
可观察集合
,但会更改集合中的一个对象。集合不知道更改其中一个对象的内部(!)状态。您的
ConfigObject
类的
PropertyChanged
事件可以捕获这些更改。

谢谢您的回答。但是您可以看到,我已经在ConfigObject类中实现了INontifyPropertyChanged接口。我对收藏中的物品所做的更改仍然不可见。你说“不可见”是什么意思?您希望在哪里看到它?我的意思是,尽管我对
ConfigObject
类的每个属性调用了
OnpropertyChanged
方法,但集合没有更新。你能告诉我在用户输入文本时更新集合所缺少的代码吗?实际上集合中没有任何更改。编辑文本框后,更改的对象将出现在您的集合中。你只是没有收到通知。ConfigObject中的PropertyChanged用于更新UI绑定,而不是我理解的CollectionKay。现在,我需要做什么才能获得更新的集合,以便在稍后获取集合时,我能够看到集合项中的UI所做的更改。感谢您的编辑Emo de Weerd先生。这将非常有帮助