问题:当属性更改时,ObservableCollection未更新为UI
我尝试了什么:
XAML视图:
<UserControl x:Class="FlexilineDotNetGui.Flexiline.UserControls.UCRealestate"
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"
mc:Ignorable="d"
xmlns:translations="clr-namespace:FlexilineDotNetGui.Flexiline.Translations"
xmlns:viewModels="clr-namespace:FlexilineDotNetGui.Flexiline.ViewModels"
x:Name="Realestate"
DataContext="{StaticResource vmRealestate}">
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<DataGrid Grid.Row="0" Grid.RowSpan="3" Grid.Column="0" Height="200" Margin="5"
ItemsSource="{Binding Panden, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" AutoGenerateColumns="False"
CanUserAddRows="False" IsReadOnly="True" SelectedItem="{Binding Pand}">
<DataGrid.Columns>
<DataGridTextColumn Header="{x:Static translations:UCRealestate.RegistrationType}" Binding="{Binding RegistrationType, Mode=TwoWay}" Width="Auto"/>
</DataGrid.Columns>
</DataGrid>
<Button Grid.Column="1" Grid.Row="0" Background="Transparent"
Width="20" Height="20" Padding="0" Margin="5" Command="{Binding AddPandCMD}"
CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type viewModels:RealestateViewModel}}}">
<Image Source="/Flexiline;component/Resources/New_16x16.ico"/>
</Button>
<Button Grid.Row="1" Grid.Column="1" VerticalAlignment="Top"
Width="20" Height="20" Padding="0" Background="Transparent" Margin="5" Command="{Binding DeletePandCMD}"
CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type viewModels:RealestateViewModel}}}">
<Image Source="/Flexiline;component/Resources/Delete_16x16.ico"/>
</Button>
<Grid Grid.Row="3" Margin="5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Row="1" Grid.Column="1" Margin="0,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MaxWidth="100"/>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
</Grid>
<Label Grid.Row="2" Grid.Column="2" Content="{x:Static translations:UCRealestate.RegistrationType}" HorizontalContentAlignment="Right" VerticalAlignment="Center"/>
<ComboBox Grid.Row="2" Grid.Column="3" Margin="5" ItemsSource="{Binding AardInschrijving, UpdateSourceTrigger=PropertyChanged}" SelectedValue="{Binding SelectedAardInschrijving, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="Description" SelectedValuePath="FlexKey"/>
</Grid>
</Grid>
</Grid>
</Grid>
</Grid>
</UserControl>
ViewModel:
using FlexilineDotNet.SharedDomainLogic.Models.CommunicationModels;
using FlexilineDotNetGui.Domain.Controls;
using FlexilineDotNetGui.Domain.Models;
using GalaSoft.MvvmLight.Command;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Data;
namespace FlexilineDotNetGui.Flexiline.ViewModels
{
public class RealestateViewModel : ANavigationPaneSubViewModel, INotifyPropertyChanged
{
BorgRealestate _borgRealestate = new BorgRealestate();
ObservableCollection<BorgRealestate> ocPanden = new ObservableCollection<BorgRealestate>();
private DomainController _controller = DomainController.GetInstance();
public RelayCommand<object> AddPandCMD { get; private set; }
public RelayCommand<object> DeletePandCMD { get; private set; }
#region "properties"
public ObservableCollection<BorgRealestate> Panden
{
get
{
return ocPanden ?? (ocPanden = new ObservableCollection<BorgRealestate>());
}
set
{
if (ocPanden == value)
return;
ocPanden = value;
OnPropertyChanged("Panden");
}
}
//public ObservableCollection<BorgRealestate> Panden { get; }
public BorgRealestate Pand
{
get
{
return _borgRealestate ?? (_borgRealestate = new BorgRealestate());
}
set
{
if (value == _borgRealestate) return;
_borgRealestate = value;
OnPropertyChanged();
OnPropertyChanged("Panden");
}
}
public List<DropDownItem> AardInschrijving { get { return _controller.GetDropDownItemsByType("AardInschrijving"); } }
private DropDownItem SelectedAardInschrijvingDI
{
get
{
DropDownItem test = _controller.GetDropDownItemsByType("AardInschrijving").FirstOrDefault(x => x.FlexKey == _borgRealestate?.RegistrationType);
if (test == null)
{
test = _controller.GetDropDownItemsByType("AardInschrijving").FirstOrDefault();
}
return test;
}
set
{
OnPropertyChanged();
OnPropertyChanged("Panden");
}
}
public int SelectedAardInschrijving
{
get
{
return SelectedAardInschrijvingDI.FlexKey;
}
set
{
if (value == Pand?.RegistrationType) return;
Pand.RegistrationType = value;
OnPropertyChanged();
OnPropertyChanged("Panden");
}
}
public string SelectedAardInschrijvingText
{
get
{
return SelectedAardInschrijvingDI.Description;
}
}
#endregion
#region "ctor"
public RealestateViewModel()
{
//Panden = new ObservableCollection<BorgRealestate>();
AddPandCMD = new RelayCommand<object>(o => AddPand());
DeletePandCMD = new RelayCommand<object>(o => DeletePand());
}
#endregion
#region "methods"
private void AddPand()
{
BorgRealestate newBorgRealestate = new BorgRealestate { RegistrationType = SelectedAardInschrijving };
Panden.Add(newBorgRealestate);
}
private void DeletePand()
{
Panden.Remove(Pand);
}
#endregion
}
}
问题描述:
当我更新组合框值时,当我使用断点检查时,它在“Panden”属性中更新,但视图中的数据网格未更新。 Oneway以及TwoWay存在问题,正如我在datagrid列中定义的那样。我尝试了两种模式。
视图位于dxnavbar控件内,当我在导航栏项目之间切换时,视图会更新确定。
编辑:
当应用程序启动时,Panden列表确实为null,我忘了提一些东西......
在我看来,有一个带有按钮的数据网格,我将项目添加到可观察集合中,其中一些属性作为示例自然题字组合框值显示在数据网格中。然后将该按钮连接到继电器命令。这是我绑定到datagridview的集合。
属性属性的getter不为空,因此填充了正确的值,只有更改在视图中不会更改。
如果没有通过UI上提供的按钮(relaycommand)将“Pand”项添加到“Panden”集合中,则集合为null是正常的。但是,在将带有按钮的项目添加到集合后,从组合框中更改值后,de datagrid中的“Pand”项将不会更新。
EDIT 21/11 08:54
这是添加pand的逻辑:
private void AddPand()
{
BorgRealestate newBorgRealestate = new BorgRealestate { RegistrationType = SelectedAardInschrijving };
Panden.Add(newBorgRealestate);
}
但是在我添加后,我看到项目被添加到集合中,并且在组合框值仅在ui中更改之后也在集合中更新。 (当数据网格中的行具有焦点时)
答案 0 :(得分:0)
在此代码中:
public ObservableCollection<BorgRealestate> Panden
{
get
{
return ocPanden ?? (ocPanden = new ObservableCollection<BorgRealestate>());
}
您创建了一个新的集合,但此时您还没有调用OnPropertyChanged;你不应该因为在这里这样做是错误的。因此,用户界面并不知道您已创建新集合。看起来第一次在AddPand函数中调用上面的getter。因此,UI永远不会收到Panden的OnPropertyChanged,因此不会更新。
而不是在构造函数中创建集合,你会发现它会更新。如果Panden从未重新创建,你可能根本不需要一个setter。
在构造函数中:
Panden = new ObservableCollection<BorgRealestate>();
然后Panden财产成为:
public ObservableCollection<BorgRealestate> Panden { get; }
可以简化为:
public ObservableCollection<BorgRealestate> Panden { get; } = new ObservableCollection<BorgRealestate>();
答案 1 :(得分:0)
在Viewmodel中:
这段简短的代码就可以解决问题:
CollectionViewSource.GetDefaultView(ocPanden).Refresh();
替换它:
public ObservableCollection<BorgRealestate> Panden
{
get
{
return ocPanden ?? (ocPanden = new ObservableCollection<BorgRealestate>());
}
set
{
if (ocPanden == value)
return;
ocPanden = value;
OnPropertyChanged("Panden");
}
}
有了这个:
public ObservableCollection<BorgRealestate> Panden
{
get
{
if(ocPanden != null)
{
CollectionViewSource.GetDefaultView(ocPanden).Refresh(); //This will do the trick
}
return ocPanden ?? (ocPanden = new ObservableCollection<BorgRealestate>());
}
set
{
if (ocPanden == value)
return;
ocPanden = value;
OnPropertyChanged("Panden");
}
}
不幸的是,我还没有找到原因的真正来源?
如果有人能够知道然后留言?