WPF - 带提示的组合框

发布于 2024-08-09 12:22:55 字数 368 浏览 4 评论 0原文

我正在寻找一种方法将“选择项目”添加到未选择项目的组合框中。这与默认选定的项目不同。

我希望组合框显示“选择一个项目”,并绑定到一个可能选择的列表和所选项目的另一个模型。

我更喜欢一种可以应用于多个组合框并有办法设置提示的样式。我在 http:// 看到了类似的内容marlongrech.wordpress.com/2008/03/09/input-prompt-support-in-wpf/,但它工作不顺利,需要点击两次才能到达列表。

谢谢!

I'm looking for a way to add a "SELECT An Item" to a combobox that does not have an item selected. This would be different than a selected item as a default.

I want the combobox to say "SELECT an Item" and be bound to one list for the possible selections and another model for the selected item.

I'd prefer a style that I can apply to multiple comboboxes and have a way to set the prompt. I've seen something similiar at http://marlongrech.wordpress.com/2008/03/09/input-prompt-support-in-wpf/, but the it does not work smoothly, requiring 2 clicks to get to the list.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

享受孤独 2024-08-16 12:22:55

您可以使用链接到的装饰器解决方案进行一些更改,或者您可以使用样式和转换器来完成此操作。

装饰器解决方案

装饰器解决方案更复杂,但具有更好的接口和封装。您需要进行的更改很简单,但如果您不是 WPF 专家,则可能会很困难。它们是:

  1. 将 ComboBox 识别为另一种特殊情况(如 TextBox)。订阅其 SelectedItemChanged,并使用 SelectedItem==null 更新装饰器可见性。

  2. 不处理输入事件(HitTestVisible=False、Focusable=False 等)

在这种情况下,您的 ComboBox 样式将为非常简单,只需设置附加属性即可。

样式和转换器

使用样式和转换器对您来说可能会更简单。这是转换器的主体:

  object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  {
    return value==null ? Visibility.Visible : Visibility.Hidden;
  }

您的样式将替换默认的 ComboBox 样式,并包含主题中的 ControlTemplate 的副本,用类似这样的东西包装(或使用装饰器):

  <Style TargetType="{x:Class ComboBox}">
    <Style.Setters>
      <Setter Property="local:MyInputPromptClass.PromptText" Value="SELECT an item" />
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="{x:Class ComboBox}">
            <Grid>
              ... existing XAML from theme ControlTemplate ...
              <TextBlock
                Text="{Binding local:MyInputPromptClass.PromptText, RelativeSource={RelativeSource TemplatedParent}}"
                Visibility="{Binding SelectedItem, Converter={x:Static local:MyInputPromptClass.Converter}, RelativeSource={RelativeSource TemplatedParent}}"
                HitTestVisible="False" Focusable="False"
                HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
            </Grid>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style.Setters>
  </Style>

此解决方案比其他解决方案不太令人满意,因为从主题复制默认的 ComboBox 模板,最终会得到一个不跟踪当前 Windows 主题的应用程序。可以使用多个 ControlTemplates 以及 StaticResource 和一些棘手的绑定来解决这个问题,但此时我建议仅使用装饰器和附加属性。

You could use the adorner solution you linked to with a couple of changes, or you could do this with a style and converter.

Adorner solution

The adorner solution is more complex, but has a better interface and encapsulation. The changes you would need to make are straightforward but possibly difficult if you're not a WPF expert. They are:

  1. Recognize ComboBox as another special case (like TextBox). Subscribe to its SelectedItemChanged, and update adorner visibility using SelectedItem==null.

  2. Don't handle input events (HitTestVisible=False, Focusable=False, etc)

In this case, your ComboBox style will be very simple, just setting the attached property.

Style and converter

Doing it with a style and converter may be simpler for you. Here is the body of the converter:

  object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  {
    return value==null ? Visibility.Visible : Visibility.Hidden;
  }

Your style will replace the default ComboBox style and contain a copy of the ControlTemplate from the theme, wrapped with something like this (or use an adorner):

  <Style TargetType="{x:Class ComboBox}">
    <Style.Setters>
      <Setter Property="local:MyInputPromptClass.PromptText" Value="SELECT an item" />
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="{x:Class ComboBox}">
            <Grid>
              ... existing XAML from theme ControlTemplate ...
              <TextBlock
                Text="{Binding local:MyInputPromptClass.PromptText, RelativeSource={RelativeSource TemplatedParent}}"
                Visibility="{Binding SelectedItem, Converter={x:Static local:MyInputPromptClass.Converter}, RelativeSource={RelativeSource TemplatedParent}}"
                HitTestVisible="False" Focusable="False"
                HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
            </Grid>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style.Setters>
  </Style>

This solution is less satisfying than the other, since by copying the default ComboBox template from a theme you end up with an app that doesn't track the current Windows theme. It's possible to get around this using multiple ControlTemplates along with StaticResource and some tricky binding, but at that point I would recommend just using the adorner and attached property.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文