簡體   English   中英

如何將ListView綁定到存儲在WPF中的單個ViewModel中的多個集合?

[英]How to bind a ListView to multiple collections stored in a single ViewModel in WPF?

我有2個集合要綁定到ListView的單獨GridViewColumn

public class EffectView : INotifyPropertyChanged
{

    ObservableCollection<Effect> effects;
    public ObservableCollection<Effect> Effects
    {
        get { return this.effects; }
        set
        {
            this.effects = value;
            this.RaisePropertyChanged ( "Effects" );
        }
    }

    ObservableCollection<EffectDescription> descriptions;
    public ObservableCollection<EffectDescription> Descriptions
    {
        get { return this.descriptions; }
        set
        {
            this.descriptions = value;
            this.RaisePropertyChanged ( "Descriptions" );
        }
    }
}

我可以做這個:

<ListView ItemsSource="{Binding EffectView.Effects}">
    <ListView.View>
        <GridView>
            <GridViewColumn Width="Auto"
                            DisplayMemberBinding="{Binding Name}"
                            Header="Name" />

            <GridViewColumn Width="Auto"
                            DisplayMemberBinding="{Binding Opacity}"
                            Header="Opacity" />

            <GridViewColumn Width="Auto"
                            DisplayMemberBinding="{Binding ?}"
                            Header="Description" />
        </GridView>
    </ListView.View>
</ListView>

但是后來所有內容都限定在EffectView.Effects ,但我希望默認范圍是EffectView這樣我就可以輕松地將多個集合分配給ListView

就像是:

<ListView ItemsSource="{Binding EffectView}">
    <ListView.View>
        <GridView>
            <GridViewColumn Width="Auto"
                            DisplayMemberBinding="{Binding Effects Path=Name}"
                            Header="Name" />

            <GridViewColumn Width="Auto"
                            DisplayMemberBinding="{Binding Effects Path=Opacity}"
                            Header="Opacity" />

            <GridViewColumn Width="Auto"
                            DisplayMemberBinding="{Binding Descriptions Path=Usage}"
                            Header="Description" />
        </GridView>
    </ListView.View>
</ListView>

有沒有辦法實現這個目標?

ListView的ItemsSource是其項目將出現在列表中的集合 那么想一想你要求ListView做什么:

  • 作為源集合,使用不是集合但包含它們的東西
  • 對於列表中的每一行,顯示一個集合中的項目和另一個集合中的項目

注意第二點:每行必須顯示Events集合中的一些項目和Descriptions集合中的一些項目。

從每個項目中選擇哪個項目? 這兩個系列中的項目之間有什么關系?

看來 ,你真正需要的是對象的集合, 同時包含一個事件和一個描述。 然后,您可以綁定到該集合以顯示兩個實體的元素。 粗略地,這樣的事情:

public class EffectView : INotifyPropertyChanged
{

    ObservableCollection<EffectsAndDescriptions> effects;
    public ObservableCollection<EffectAndDescriptions> Effects
    {
        get { return this.effects; }
        set
        {
            this.effects = value;
            this.RaisePropertyChanged ( "EffectsAndDescriptions" );
        }
    }

}

internal class EffectsAndDescriptions
{
    public Effect Effect { get; set; }
    public Description Description { get; set; }
}

現在您可以綁定到EffectsAndDescriptions集合(請注意,這假設ListView的父級的DataContext是EffectView

<ListView ItemsSource="{Binding EffectsAndDescriptions}">
    <ListView.View>
        <GridView>
            <GridViewColumn Width="Auto"
                            DisplayMemberBinding="{Binding Effect.Name}"
                            Header="Name" />

            <GridViewColumn Width="Auto"
                            DisplayMemberBinding="{Binding Effect.Opacity}"
                            Header="Opacity" />

            <GridViewColumn Width="Auto"
                            DisplayMemberBinding="{Binding Description.Usage}"
                            Header="Description" />
        </GridView>
    </ListView.View>
</ListView>

那不太可能。 ItemsSource期望傳遞一些至少實現IEnumerable的東西。 即使您在EffectView上實現了IEnumerable,也需要將Effect和EffectDescription包裝到單個對象中以進行返回。

您可以將ListView綁定到Effects集合,然后使用自定義IValueConverter獲取效果並返回描述。 但我不確定這適合你的情況。

您最好的選擇是包含一個包含您的效果和EffectDescription的包裝器對象(即EffectWithDescription)。 然后公開EffectWithDescription對象的集合。 您需要確保此新集合與其他集合保持同步。

暫無
暫無

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

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