Laden...

[erledigt] ListView ItemsSource wann gefüllt?

Erstellt von Maliko vor 9 Jahren Letzter Beitrag vor 9 Jahren 2.552 Views
M
Maliko Themenstarter:in
117 Beiträge seit 2012
vor 9 Jahren
[erledigt] ListView ItemsSource wann gefüllt?

Hoi,

ich hab da gerade ein kleines Problem und stehe auf dem Schlauch. Vielleicht könnt ihr mir da ein wenig weiterhelfen.

Und zwar habe ich eine ListView, welche ich mit Daten fülle. Die Daten werden auch angezeigt, wenn ich dann allerdings versuche ne Filterung zu bauen, habe ich das Problem, dass das ItemsSource-Property der ListView wenn das DataContextChanged-Event feuert noch null ist. Ich hab mal geschaut ob in ItemsSource überhaupt was drin ist und wenn ich im SelectionChanged-Event nen Breakpoint setze ist ItemsSource auch gefüllt.

Nun zu meiner Frage. Welches Event nutze ich am besten um die CollectionView für die ListView zu definieren (da DataContextChanged ja scheinbar zu früh ist).

Hier der Code so wie ich ihn derzeit habe:

View:


<ListView Grid.Row="1" Name="lv_Leistungserbringer" DataContextChanged="lv_Leistungserbringer_DataContextChanged" SelectionChanged="lv_Leistungserbringer_SelectionChanged" ItemsSource="{Binding Path=Leistungserbringer}" Height="150" VerticalAlignment="Bottom">
    <ListView.View>
        <GridView>
            [...] <!-- Hab die Columns mal rausgenommen wegen Platz-->
        </GridView>
    </ListView.View>
</ListView>

CodeBehind:


private void lv_Leistungserbringer_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(lv_Leistungserbringer.ItemsSource);
    view.Filter = this.Filter;
}

private bool Filter(object item)
{
    if (String.IsNullOrEmpty(tb_Search.Text))
        return true;
    else
    {
        int test;
        int.TryParse(tb_Search.Text, out test);

        if (test == 0)
            return ((item as ILeistungserbringer).Beschreibung.IndexOf(tb_Search.Text, StringComparison.OrdinalIgnoreCase) >= 0);
        else
            return ((item as ILeistungserbringer).ID.ToString().IndexOf(tb_Search.Text, StringComparison.OrdinalIgnoreCase) >= 0);
    }
}

Das Binding der Source läuft über ein ViewModel ab, welches an den DataContext gebunden wurde.

Kann mir da vielleicht jemand nen Anstoß geben wo ich da ansetzen muss?

Danke schon mal im Vorraus.

LG
Maliko

2.207 Beiträge seit 2011
vor 9 Jahren

Hallo Maliko,

wieso benutzt du das DataContextChanged-Event?

Gruss

Coffeebean

M
Maliko Themenstarter:in
117 Beiträge seit 2012
vor 9 Jahren

Weil als das ganze noch nicht MVVM war, dort das Objekt gefüllt war.

Ich habs inzwischen allerdings komplett umgestellt. Der Filter ist ebenfalls ins ViewModel gewandert (so wie es sich auch gehört).

View:


<TextBox Width="200" Margin="0,0,0,5" x:Name="tb_Search" Text="{Binding Path=FilterValue, UpdateSourceTrigger=PropertyChanged}"/>
<ListView Grid.Row="1" Name="lv_Leistungserbringer" SelectionChanged="lv_Leistungserbringer_SelectionChanged" ItemsSource="{Binding Path=LeistungserbringerCollection}" Height="150" VerticalAlignment="Bottom">
    <ListView.View>
        <GridView>
            [...] <!-- Hab die Columns mal rausgenommen wegen Platz-->
        </GridView>
    </ListView.View>
</ListView>

ViewModel:


//Die Datenquelle
private ObservableCollection<ILeistungserbringer> _Leistungserbringer;
public ObservableCollection<ILeistungserbringer> Leistungserbringer
{
    get { return this._Leistungserbringer; }
    set 
    { 
        this._Leistungserbringer = value;
        this._LeistungserbringerCollection = CollectionViewSource.GetDefaultView(this.Leistungserbringer);
        this._LeistungserbringerCollection.Filter = this.Filter;

        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs("Leistungserbringer"));
    }
}

//Die Collection der Datenquelle, die gebunden wird
private ICollectionView _LeistungserbringerCollection;
public ICollectionView LeistungserbringerCollection
{ 
    get { return this._LeistungserbringerCollection; }
}

//Der Filterbegriff
private string _FilterValue;
public string FilterValue
{
    get { return this._FilterValue; }
    set
    {
        this._FilterValue = value;

        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs("FilterValue"));

        this._LeistungserbringerCollection.Refresh();
    }
}

//Die Filtermethode
private bool Filter(object item)
{
    if (item != null)
    {
        if (String.IsNullOrEmpty(this._FilterValue))
            return true;
        else
        {
            int test;
            int.TryParse(this._FilterValue, out test);

            if (test == 0)
                return ((item as ILeistungserbringer).Beschreibung.IndexOf(this._FilterValue, StringComparison.OrdinalIgnoreCase) >= 0);
            else
                return ((item as ILeistungserbringer).ID.ToString().IndexOf(this.FilterValue, StringComparison.OrdinalIgnoreCase) >= 0);
        }
    }
    else
        return false;
}

2.207 Beiträge seit 2011
vor 9 Jahren

Hallo Maliko,

ich verstehe noch nicht ganz, warum du noch eine ObservableCollection hast. Die benutzt du auch, zumindest in dem XAML hier, nicht. Schmeiss die mal raus und benutze nur deine CollectionView.

Gruss

Coffeebean

Edit: Ah, sehe gerade, dass sich dsa Problem erledigt hat. 😉

M
Maliko Themenstarter:in
117 Beiträge seit 2012
vor 9 Jahren

Die Fliegt auch noch raus. Ist momentan nur ne Übergangslösung, da die Daten derzeit noch über die ObservableCollection kommen. Das wird aber noch umgestellt und dann fliegt auch die ObservableCollection raus.

5.299 Beiträge seit 2008
vor 9 Jahren

ich lass die ObservableCollections immer fein drinne, im Viewmodel.
Weil damit kann man die Daten addressieren, ohne jedesmal einen Cast ausführen zu müssen.

Der frühe Apfel fängt den Wurm.