在Josh Smith的文章之后,在MVVM中的ListView中添加ComboBox

时间:2011-07-28 19:47:24

标签: wpf xaml mvvm combobox viewmodel

我最近开始使用MVVM开发WPF应用程序。我关注Josh Smith's article。我编写了一个基本屏幕,它只是从ViewModel的ObservableCollection类中显示ListView中的数据。这是一个List<string>。我只是希望能够显示字符串列表,而不是能够将它保存回父集合的基础属性中。

我应该使用RelativeSource与ViewModel作为DataContext链接吗?

这是ViewModel代码。

public class ViewModel
{
    public List<string> AndOrList
    {
        get 
        {
            List<string> andOrList = new List<string> { "AND", "OR" };
            return andOrList;
        }
    }

    public ObservableCollection<BusObjects.Criterion> Criteria
    {
        get
        {
            return new ObservableCollection<BusObjects.Criterion>(_stream.ParseFilterCriteria().Criterias);
        }
    }
}

这是问题区

<GridViewColumn Header="And / Or">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <ComboBox ItemsSource="{Binding AndOrList}">
                                </ComboBox>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>

这是整个XAML代码。我试图将AndOrList集合绑定到ComboBox。

<UserControl.Resources>
    <local:FilterCriteriaConverter x:Key="FilterCriteriaConverter"/>

    <CollectionViewSource x:Key="CriteriaList"
                          Source="{Binding Path=Criteria}">
        <CollectionViewSource.SortDescriptions>
            <scm:SortDescription PropertyName="DimName" Direction="Ascending"/>
        </CollectionViewSource.SortDescriptions>
    </CollectionViewSource>

    <Style x:Key="CriteriaItemStyle" TargetType="{x:Type ListViewItem}">
        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
        <Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" />
        <Style.Triggers>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="ItemsControl.AlternationIndex" Value="1" />
                    <Condition Property="IsSelected" Value="False" />
                    <Condition Property="IsMouseOver" Value="False" />
                </MultiTrigger.Conditions>
                <Setter Property="Background" Value="#EEEEEEEE" />
            </MultiTrigger>
        </Style.Triggers>
    </Style>
</UserControl.Resources>

<DockPanel>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="5"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <ListView 
              Name="lstCriteria"
              Grid.Row="0"
              AlternationCount="2" 
              DataContext="{StaticResource CriteriaList}" 
              ItemContainerStyle="{StaticResource CriteriaItemStyle}"
              ItemsSource="{Binding}" DockPanel.Dock="Top">
            <ListView.Resources>
                <Style TargetType="ListViewItem">
                    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                </Style>
            </ListView.Resources>
            <ListView.View>
                <GridView>
                    <GridViewColumn>
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <Rectangle Fill="SteelBlue" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Header="And / Or">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <ComboBox ItemsSource="{Binding AndOrList}">
                                </ComboBox>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Path=DimName}" />
                    <GridViewColumn Header="Oprator" DisplayMemberBinding="{Binding Path=Operator}" />
                    <GridViewColumn Header="Value" DisplayMemberBinding="{Binding Path=DimValue}" />

                </GridView>
            </ListView.View>
        </ListView>
        <Border Grid.Row="1" CornerRadius="4" BorderThickness="1">
            <GridSplitter HorizontalAlignment="Stretch" VerticalAlignment="Center" 
                  Height="3"
                  Background="SteelBlue"/>
        </Border>                
        <Border Name="xmlBorder" Grid.Row="2" VerticalAlignment="Stretch" CornerRadius="4" BorderThickness="1" >
            <StackPanel x:Name="stkPanel" Grid.Row="2" Height="Auto" VerticalAlignment="Stretch" >
                <XMLViewer:Viewer x:Name="xmlViewer" VerticalAlignment="Stretch" />
                <TextBox x:Name="txtXml" TextChanged="XmlTextChanged" Visibility="Hidden"
                         Text="{Binding Path=FilterCriteria, 
                            Converter={StaticResource FilterCriteriaConverter}}" TextWrapping="Wrap"/>
            </StackPanel>
        </Border>
    </Grid>
</DockPanel>

由于

1 个答案:

答案 0 :(得分:1)

我会前往DataContext仍然是视图模型的位置,将路径更改为DataContext.AndOrList并添加RelativeSource找到相应的控件。

此外,我不会更改ListView的DataContext,只需将所有内容放入ItemsSource绑定中:

<ListView ItemsSource="{Binding Source={StaticResource CriteriaList}}" ...>

然后以下情况应该起作用,并且几乎是最小的:

<ComboBox ItemsSource="{Binding DataContext.AndOrList, RelativeSource={RelativeSource AncestorType=ListView}}">