我在WPF中的應用程序中遇到了一個非常奇怪的問題,其中很多屏幕在綁定和組合框中工作得很好。但其中一個正在導致我的問題。ListView滾動觸發器Combobox SelectedValue並拋出異常
我創建了一個屏幕來爲應用中定義的每個用戶定義一個配置文件。所以它是一個Listview,每行都是一個標籤(用戶名)和一個帶有配置文件列表的組合框。 一切都是通過綁定來定義的。
這裏是爲ListView的XAML(我刪除樣式):
<ListView Name="lv_UserProfils" ItemsSource="{Binding ListeEntites}" AlternationCount="2"
ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollBarVisibility="Auto">
<ListView.View>
<GridView>
<GridViewColumn Header="Nom d'utilisateur" Width="250">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Border Height="25">
<TextBlock Text="{Binding UserLogin}" Width="Auto" />
</Border>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Profil" Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox
ItemsSource="{Binding DataContext.ListeProfils, ElementName=lv_UserProfils}"
DisplayMemberPath="LibProfil" SelectedValuePath="IdProfil"
SelectedValue="{Binding Profil.IdProfil}"
SelectedItem="{Binding Profil}" Width="200" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
的DataContext
是一個自定義視圖模型類的實例,它提供了一個ObservableCollection<UserBE>
命名ListeEntites
UserBE
是多還是少:
public sealed class UserBE
{
public bool IsAdmin { get; set; }
public bool IsUpdateGranted { get; set; }
private string _userLogin;
public string UserLogin
{
get { return _userLogin; }
set { _userLogin = value; OnPropertyChanged("UserLogin"); }
}
private ProfilBE _profil;
public ProfilBE Profil
{
get { return _profil; }
set
{
_profil = value;
OnPropertyChanged("Profil");
}
}
}
而且ProfilBE
是
public sealed class ProfilBE
{
public long IdProfil { get; set; }
private string _codProfil;
public string CodProfil
{
get { return _codProfil; }
set { _codProfil = value; OnPropertyChanged("CodProfil"); }
}
private string _libProfil;
public string LibProfil
{
get { return _libProfil; }
set { _libProfil = value; OnPropertyChanged("LibProfil"); }
}
}
這是我的問題:
用戶列表很長,所以有一個滾動條。我可以儘可能多地滾動,但只要向上滾動(但只有當我向下滾動時),所有未顯示的組合框一出現在屏幕上就會被清除。
有趣的事實:
- 當我滾動時,將
Profil
制定者不斷呼籲與顯示的行相關聯的對象。我不知道爲什麼(沒有原因,Profil
財產已被定義) - 在一個點上,如果我向上滾動,我得到了很多的異常的,和
Profil
制定者開始接受null
作爲價值
。
System.Windows.Data Error: 23 : Cannot convert 'BanquePrivee.AssuranceVie.Net.BE.ProfilBE' from type 'ProfilBE' to type 'System.Int64' for 'fr-FR' culture with default conversions; consider using Converter property of Binding. NotSupportedException:'System.NotSupportedException: Int64Converter cannot convert from BanquePrivee.AssuranceVie.Net.BE.ProfilBE.
at System.ComponentModel.TypeConverter.GetConvertFromException(Object value)
at System.ComponentModel.TypeConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
at System.ComponentModel.BaseNumberConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
at MS.Internal.Data.DefaultValueConverter.ConvertHelper(Object o, Type destinationType, DependencyObject targetElement, CultureInfo culture, Boolean isForward)'
System.Windows.Data Error: 7 : ConvertBack cannot convert value 'BanquePrivee.AssuranceVie.Net.BE.ProfilBE' (type 'ProfilBE'). BindingExpression:Path=Profil.IdProfil; DataItem='UserBE' (HashCode=59629589); target element is 'ComboBox' (Name=''); target property is 'SelectedValue' (type 'Object') NotSupportedException:'System.NotSupportedException: Int64Converter cannot convert from BanquePrivee.AssuranceVie.Net.BE.ProfilBE.
at MS.Internal.Data.DefaultValueConverter.ConvertHelper(Object o, Type destinationType, DependencyObject targetElement, CultureInfo culture, Boolean isForward)
at MS.Internal.Data.ObjectTargetConverter.ConvertBack(Object o, Type type, Object parameter, CultureInfo culture)
at System.Windows.Data.BindingExpression.ConvertBackHelper(IValueConverter converter, Object value, Type sourceType, Object parameter, CultureInfo culture)'
這很明顯,SelectedValue="{Binding Profil.IdProfil}"
是問題,但我不明白爲什麼。
我不明白爲什麼在某些時候它會試圖將IdProfil
轉換爲ProfilBE
。我不應該在那裏使用一個轉換器。
我做了很多測試,數據似乎沒有問題(沒有空值,應該沒有的地方等)
有人能指出我在哪裏做錯了什麼嗎?
明天我再試一次,但我覺得如果沒有這兩種方法,我不會按照我想要的方式工作。我在應用程序中的任何地方都使用這種代碼,而當它不在滾動列表視圖中時,它似乎可以工作。我認爲,如果你不指定它將嘗試改變當前的'UserBE.Profil.IdProfil'值,而我想要的是用選定的一個替換完整的'UserBE.Profil'對象。 –
@JulienN兩種方法做同樣的事情,但如果你想使用'SelectedItem',而不是'SelectedValue'和'SelectedValuePath'然後是確保該項目是指存儲在您的ItemsSource的項目之一完全相同的參考或WPF不會考慮它的匹配和選擇項目(或者你可以覆蓋.Equals()ProfileBE的方法,如果'IdProfil'匹配返回true) – Rachel
我同意,但對象是不一樣的,他們是未在相同位置初始化。唯一的「關係」是ID。但是重寫'Equals()'本來就是一個很好的解決方案來取代我對Combobox屬性的雙重使用(不確定它是否會解決我的問題)。我應該從一開始就這樣做:) –