WPF:绑定两个不同的列表

时间:2015-04-03 16:44:00

标签: c# wpf list listbox

我在WPF中有一些数据绑定问题。

我有一个ListBox,它绑定到BindingList。

<ListBox x:Name="SampleListBox" ItemsSource="{Binding List1}" ItemContainerStyle="{StaticResource ListBoxStyle}" BorderThickness="0" SelectedIndex="0" Margin="0">
            <ListBox.ItemTemplate>
                <DataTemplate >
                    <Border x:Name="border" Width="185">
                        <TextBlock Text="{Binding name}"/>
                    </Border>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

直到这里,一切正常。现在我有一个DataGrid,它应该链接到另一个BindingList并显示它的一些字符串。因此,例如,如果选择了ListBox的第一项,则网格应该显示第二列表的第一项的数据。 我知道,如果ListBox和Grid都从同一个列表中获取数据,它将如何工作,但我不知道,该怎么办,如果这是不可能的,并且有两个不同的列表。

2 个答案:

答案 0 :(得分:0)

您可以将ListBox控件的SelectedIndex绑定到ViewModel中Int(Property1)类型的属性。

还将DataGrid中的SelectedItem双向绑定到第二个列表类型的另一个属性(Property2)。

在Property1的setter中,将Property2更改为Property1索引处的项目 - 即List2 [Property1]。它应该更改DataGrid中的选定项目。

答案 1 :(得分:0)

所以你想使用列表框,基本上在网格上设置一个过滤器?

请注意,下面的LBItem和ViewModel需要实现INotifyPropertyChanged并在属性更改时触发其PropertyChanged事件,否则这些事件都不起作用。但为了清晰起见,我将遗漏了样板。

有很多方法可以做到这一点。

C#

public class LBItem {
    public ViewModel Parent { get; set; }
    public IEnumerable<String> SubItems {
        get {
            return Parent.List2.Where( /* filter items here */ );
        }
    }
}

public class ViewModel {
    //  
    public ObservableCollection<LBItem> LBItems { get; set; }
    public LBItem SelectedLBItem { get; set; } 
    public List<String> List2 { get; set; }
}

XAML

<ListBox 
    Name="MasterLB"
    ItemsSource="{Binding LBItems}" 
    SelectedItem={Binding SelectedLBItem}"
    />

<DataGrid
    ItemsSource="{Binding ElementName=MasterLB, Path=SelectedItem.SubItems}"
    />

无论您是否将MasterLB.SelectedItem绑定到ViewModel上的属性,这都会有效。但只要您绑定MasterLB.SelectedItem,就可以轻松地将DataGrid.ItemsSource绑定到ViewModel上的SelectedLBItem.SubItems,如下所示:

<DataGrid
    ItemsSource="{Binding Path=SelectedLBItem.SubItems}"
    />

但是ElementName绑定很方便,所以我给你们两个。

您也可以这样做:

C#

public class LBItem {
    public IEnumerable<String> Filter(IEnumerable<String> fullList) {
        return fullList.Where( /* filter items here */ );
    }
}

public class ViewModel {
    public ObservableCollection<LBItem> LBItems { get; set; }
    private LBItem _selectedItem;
    public LBItem SelectedLBItem { 
        get { return _selectedItem; }
        set {
            _selectedItem = value;
            List2Filtered = (null == _selectedItem) 
                ? new List<String>() 
                : _selectedItem.Filter(List2).ToList();
        }
    } 
    public List<String> List2 { get; set; }
    public List<String> List2Filtered { get; set; }
}

XAML

<ListBox 
    Name="MasterLB"
    ItemsSource="{Binding LBItems}" 
    SelectedItem={Binding SelectedLBItem}"
    />

<DataGrid
    ItemsSource="{Binding List2Filtered}"
    />