1

多くの画面がバインドとコンボボックスで非常にうまく機能している WPF のアプリで、非常に奇妙な問題が発生しています。しかし、それらの1つが私に問題を引き起こしています。

アプリで定義された各ユーザーにプロファイルを定義する画面を作成しました。これは、各行がラベル (ユーザー名) であるリストビューと、プロファイルのリストを含むコンボボックスです。すべてがバインディングによって定義されます。

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>

は、名前付き ListeEntitesDataContextを提供するカスタム ViewModel クラスのインスタンスです。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セッター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}"理由はわかりません。ある時点で を にキャストしよう
とする理由がわかりません。そこでコンバーターを使用する必要はありません。 私は多くのテストを行いましたが、データは問題ないようです (あるべきでない場所に null 値がないなど)。IdProfilProfilBE

誰かが私が何か間違ったことをした場所を教えてもらえますか?

4

2 に答える 2

1

SelectedValueとの両方を設定することと関係があると思いますSelectedItem。どちらのプロパティも同じことを行います。選択したアイテムを設定します。ただし、1つは、がValue何であるかに基づいて設定し、もう1つSelectedValuePathは、単に。内のアイテムに設定しますItemsSource

SelectedValueWPFがどこかで混乱していて、 (int)をSelectedItemタイプのであるに設定しようとしていると推測しています。intとしてキャストできないProfilBEため、例外がスローされます。ProfilBE

しかしとにかく、それを修正するにSelectedItemは、ComboBoxのバインディングを削除してみてください

<ComboBox ItemsSource="{Binding DataContext.ListeProfils, ElementName=lv_UserProfils}" 
    DisplayMemberPath="LibProfil" SelectedValuePath="IdProfil" 
    SelectedValue="{Binding Profil.IdProfil}" 
    Width="200" />
于 2012-09-27T18:56:43.777 に答える
0

WPF は、現在表示されていないオブジェクトを仮想化しています。しかし、上にスクロールしようとすると、仮想化されて再び画面に表示されようとしている項目で機能しないことをしようとしているようです。

私が使用した解決策は、を使用して 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>
于 2012-09-28T14:44:54.727 に答える