簡體   English   中英

Listview滾動觸發Combobox SelectedValue並引發異常

[英]Listview scrolling triggers Combobox SelectedValue and throws exception

我在WPF中的一個應用程序中遇到了一個非常奇怪的問題,其中很多屏幕與綁定和組合框的工作都非常好。 但是其中之一導致了我的麻煩。

我創建了一個屏幕來為應用程序中定義的每個用戶定義一個配置文件。 因此,這是一個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是自定義ViewModel類的實例,該類提供了名為ListeEntites的ObservableCollection<UserBE>

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異常,並且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 我不必在那里使用Converter。
我做了很多測試,數據似乎還不錯(在不應有的地方沒有空值,等等)。

有人可以指出我做錯了什么嗎?

我認為這與設置SelectedValueSelectedItem 這兩個屬性執行相同的操作:它們設置選定的項目。 但是,一個基於Value基於SelectedValuePath是什么來設置它,另一個則只是將它設置為ItemsSource一個項目。

我猜想WPF在某個地方變得很困惑,並試圖將SelectedValue (它是一個int )設置為SelectedItem ,它是ProfilBE類型,並且由於ProfilBE無法轉換為int而引發了異常。

但是無論如何,要解決此問題,請嘗試刪除ComboBox中的SelectedItem綁定

<ComboBox ItemsSource="{Binding DataContext.ListeProfils, ElementName=lv_UserProfils}" 
    DisplayMemberPath="LibProfil" SelectedValuePath="IdProfil" 
    SelectedValue="{Binding Profil.IdProfil}" 
    Width="200" />

WPF正在虛擬化當前未顯示的對象。 但是,當我嘗試向上滾動時,似乎嘗試對虛擬化並即將再次出現在屏幕上的項目不起作用。

我使用的解決方案是使用VirtualizingStackPanel.IsVirtualizing="False"禁用ListView的VirtualizingStackPanel.IsVirtualizing="False" 它對性能的影響不大,但現在可以使用。

<ListView Name="lv_UserProfils" ItemsSource="{Binding ListeEntites}" AlternationCount="2" VirtualizingStackPanel.IsVirtualizing="False"
        ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollBarVisibility="Auto">
    <ListView.View>
        [...]
    </ListView.View>
</ListView>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM