当WPF ComboBox的选择为空时,它是否可以显示替代文本?

Gar*_*idd 10 wpf null xaml combobox

天儿真好!

我希望我的WPF ComboBox在其数据绑定选择时显示一些替代文本null.

视图模型具有预期的属性:

public ThingoSelectionViewModel : INotifyPropertyChanged {
    public ThingoSelectionViewModel(IProvideThingos) {
        this.Thingos = IProvideThingos.GetThingos();
    }

    public ObservableCollection<Thingo> Thingos { get; set; }

    public Thingo SelectedThingo { 
        get { return this.selectedThingo; }
        set { // set this.selectedThingo and raise the property change notification
    }

    // ...

}
Run Code Online (Sandbox Code Playgroud)

该视图以预期的方式将XAML绑定到视图模型:

<ComboBox x:Name="ComboboxDrive" SelectedItem="{Binding Path=SelectedThingo}"
          IsEditable="false" HorizontalAlignment="Left" MinWidth="100" 
          IsReadOnly="false" Style="{StaticResource ComboboxStyle}"
          Grid.Column="1" Grid.Row="1" Margin="5" SelectedIndex="0">
    <ComboBox.ItemsSource>
        <CompositeCollection>
        <ComboBoxItem IsEnabled="False">Select a thingo</ComboBoxItem>
        <CollectionContainer 
            Collection="{Binding Source={StaticResource Thingos}}" />
        </CompositeCollection>
    </ComboBox.ItemsSource>
</ComboBox>
Run Code Online (Sandbox Code Playgroud)

ComboBoxItem楔入顶部的方式在顶部得到一个额外的项目.它是纯铬:视图模型保持纯粹和简单.只有一个问题:当ComboBox的选择为空时,用户希望显示"Select a thingo".

用户希望默认选择thingo.他们希望看到一条消息告诉他们选择一个东西.

我想避免使用ThingoWrapper带有ToString返回"Select a thingo" 的方法的类来污染viewmodel,如果它的.ActualThingo属性为null,则将每个包装Thingo为我填充Thingos,并找出一些方法来阻止用户选择nulled Thingo.

有没有办法ComboBox在视图的代码隐藏类中使用纯XAML或纯XAML和几行代码在'边界内显示"选择一个东西" ?

Rob*_*ins 8

您的MVVM要求有多严格?你能在视图中看到一些代码隐藏吗?

也许你可以在网格中包含ComboBox,如下所示:

<Grid>
    <ComboBox x:Name="ComboBoxControl"
              SelectionChanged="ComboBoxControl_SelectionChanged"
              HorizontalAlignment="Left" VerticalAlignment="Top" 
              MinWidth="{Binding ElementName=UnselectedText, Path=ActualWidth}">
        <ComboBoxItem>One</ComboBoxItem>
        <ComboBoxItem>Two</ComboBoxItem>
        <ComboBoxItem>Three</ComboBoxItem>
    </ComboBox>
    <TextBlock IsHitTestVisible="False" 
               x:Name="UnselectedText" 
               HorizontalAlignment="Left" 
               Text="Select an option..." 
               VerticalAlignment="Top" Margin="4" 
               Padding="0,0,30,0" />
</Grid>
Run Code Online (Sandbox Code Playgroud)

然后,在代码隐藏中,在事件处理程序中插入一些逻辑:

Private Sub ComboBoxControl_SelectionChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs)
    If ComboBoxControl.SelectedIndex = -1 Then
        UnselectedText.Visibility = Windows.Visibility.Visible
    Else
        UnselectedText.Visibility = Windows.Visibility.Hidden
    End If
End Sub
Run Code Online (Sandbox Code Playgroud)

IsHitTestVisible="False"在TextBlock上设置DependencyProperty允许鼠标事件通过,以便您可以单击ComboBox,并Hidden在代码隐藏中设置可见性,以便在隐藏提示文本时保持默认ComboBox外观的布局.


Ste*_*rex 5

您不能使用控件模板触发器,但可以为组合框设置一个简单的项目模板:

<ComboBox ItemsSource="{Binding}" >
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <TextBlock x:Name="displayText" Text="{Binding}" />
                <DataTemplate.Triggers>
                    <DataTrigger Binding="{Binding}" Value="{x:Null}">
                        <Setter TargetName="displayText" Property="Text" Value="Default Value" />
                    </DataTrigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>
Run Code Online (Sandbox Code Playgroud)


Mic*_*own 3

我发现这里阻力最小的路径是使用Null 对象模式对于在 .NET Framework 中使用此模式的示例,如果您为 Thingo 创建 Null 对象,请考虑静态值 Double.NaN,在查看模型,您可以将其附加到列表的前面以表示“未选择任何内容”。为 Thingo 类创建一个 DataTemplate,该类具有用于显示“选择值”的 Null 对象实例的 DataTrigger。

我可以提供一个代码示例,但已经过了我的睡觉时间。