如何手动将元素添加到绑定的组合框而不将其添加到集合?

时间:2018-10-29 16:50:02

标签: c# wpf xaml mvvm

我有一个ComboBox,其中的ItemsSource绑定到ObservableCollection。我只想在View上将NONE值附加到Collection的前面。我不想仅将这个附加值添加到绑定的Collection中,仅用于ComboBox项。我一直在尝试ComboBoxItems,但这似乎不起作用,因为它实际上并没有添加。

这是我的XAML:

                        <ContentControl Content="{Binding Developer.Games}" Height="25" Width="177">
                        <ContentControl.ContentTemplate>
                            <DataTemplate>
                                <Grid>
                                    <ComboBox x:Name="cb" ItemsSource="{Binding}" DisplayMemberPath="Date"/>
                                    <TextBlock x:Name="tb" Text="Select Game" IsHitTestVisible="False" Visibility="Hidden" TextAlignment="Center" VerticalAlignment="Center"/>
                                </Grid>
                                <DataTemplate.Triggers>
                                    <Trigger SourceName="cb" Property="SelectedItem" Value="{x:Null}">
                                        <Setter TargetName="tb" Property="Visibility" Value="Visible"/>
                                    </Trigger>
                                </DataTemplate.Triggers>
                            </DataTemplate>
                        </ContentControl.ContentTemplate>
                    </ContentControl>

因此,我希望我的收藏集在展开的下拉菜单中看起来像这样:

NONE
Game1
Game2
Game3

3 个答案:

答案 0 :(得分:0)

  

我不想将此附加值实际添加到绑定的Collection

简短的答案是您绑定到数据源的内容是您从控件中看到的内容。

考虑到这一点,您应该做的只是不从外部绑定数据源,而是在内部用额外的项创建一个新的数据源(这意味着您应该在自定义派生类中进行操作)并绑定它。您只需确保使用标准的可观察事件使数据源与外部数据源保持同步。

答案 1 :(得分:0)

WPF可以使用IValueConverter在VM和视图之间更改值。您可以执行以下操作:

public class GameListEmptyOptionValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var v = value as ObservableCollection<Game>;
        v?.Insert(0, new Game() { Name = "NONE" });
        return v;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
}

,并在您的视图上使用它:

<Window.Resources>
    <local:GameListEmptyOptionValueConverter x:Key="GameListEmptyOptionValueConverter"/>
</Window.Resources>
<Grid>
    <ComboBox ItemsSource="{Binding ., Converter={StaticResource GameListEmptyOptionValueConverter}}" DisplayMemberPath="Name"/>
</Grid>

答案 2 :(得分:0)

您可以使用CompositeCollection。 这是一个基于您提供的XAML代码的示例,该示例添加了一个带有文本“ NONE”的ListBoxItem作为第一项,并在视图模型中显示了其余对象。

<ComboBox x:Name="cb">
    <ComboBox.Resources>
        <CollectionViewSource x:Key="GamesCollection" Source="{Binding}"/>
    </ComboBox.Resources>
    <ComboBox.ItemsSource>
        <CompositeCollection>
            <ListBoxItem>NONE</ListBoxItem>
            <CollectionContainer Collection="{Binding Source={StaticResource GamesCollection}}"/>
        </CompositeCollection>
    </ComboBox.ItemsSource>
</ComboBox>