XAML 只读组合框

发布于 2024-10-16 01:14:22 字数 597 浏览 2 评论 0原文

要在 XAML (WPF) 中设置只读 ComboBox,您必须设置一个 ComboBox 和一个 TextBox,根据ViewModel 上必须存在的一对属性 IsReadOnly/IsEditable。请注意,在此示例中,“UserNVL”必须存在于资源中,并且它应该是一个 NameValueList 集合,允许我们将 ID 转换为名称。在本例中,RecipientID 是用户名的键。另请注意,VisibilityConverter 也必须存在于资源中,并且它是标准的 BooleanToVisibilityConverter

天哪!这太难找到了,我必须自己做。这允许用户选择文本框的内容。禁用的 ComboBox 绝不允许您执行此操作。

To set up a ReadOnly ComboBox in XAML (WPF), you have to set up a ComboBox and a TextBox showing only one of them according to a pair of properties IsReadOnly/IsEditable that must exist on your ViewModel. Note that on this sample "UserNVL" must exist in the resources and it should be a NameValueList collection that allows us to convert ID to names. In this case the RecipientID is the key for a user name. Note also the VisibilityConverter must also exist in the resources and it's a standard BooleanToVisibilityConverter.

Gosh! This was so hard to find I had to made it myself. This allows the user the select the content of the text box. No way a disabled ComboBox would ever allow you to do it.

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

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

发布评论

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

评论(6

紫罗兰の梦幻 2024-10-23 01:14:23

有两个名为 IsHitTestVisible 和 IsHitTestVisible 的属性。 IsTabVisible。前者使控件对鼠标事件充耳不闻,后者对键盘事件充耳不闻。
这可以帮助您,因为它不会给您的组合框提供禁用的外观,但您将成功制作只读组合框。
来源 :-
http://www.telerik.com /community/forums/wpf/combobox/isreadonly-does-sem-to-work.aspx

There are two properties named IsHitTestVisible & IsTabVisible. the former makes the control deaf to mouse events and the latter to keyboard events.
This could help you as it would not give the disabled look to your combo box but you will succeed in making a read only combo box..
Source :-
http://www.telerik.com/community/forums/wpf/combobox/isreadonly-does-seem-to-work.aspx

べ映画 2024-10-23 01:14:23

为什么不直接设置 IsEnabled=false 呢?

Why not just set IsEnabled=false?

心房的律动 2024-10-23 01:14:23
<DockPanel>
  <TextBlock Text="Recipient" Margin="6,9,3,6" HorizontalAlignment="Right"/>
  <ComboBox
      x:Name="RecipientID"
      ItemsSource="{Binding Source={StaticResource UserNVL}}"
      DisplayMemberPath="Value"
      SelectedValuePath="Key"
      SelectedValue="{Binding Path=RecipientID}"
      Height="20"
      Margin="6,6,0,6"
      MinWidth="200"
      HorizontalAlignment="Left"
      IsEditable ="True"
      Visibility="{Binding Path=IsEditable, Converter={StaticResource VisibilityConverter}}"/>
  <TextBox
      x:Name="RecipientName"
      Text="{Binding ElementName=RecipientID, Path=Text}"
      Margin="6,6,0,6"
      MinWidth="200"
      HorizontalAlignment="Left"
      Style="{StaticResource textBoxInError}"
      Visibility="{Binding Path=IsReadOnly, Converter={StaticResource VisibilityConverter}}"/>
</DockPanel>
<DockPanel>
  <TextBlock Text="Recipient" Margin="6,9,3,6" HorizontalAlignment="Right"/>
  <ComboBox
      x:Name="RecipientID"
      ItemsSource="{Binding Source={StaticResource UserNVL}}"
      DisplayMemberPath="Value"
      SelectedValuePath="Key"
      SelectedValue="{Binding Path=RecipientID}"
      Height="20"
      Margin="6,6,0,6"
      MinWidth="200"
      HorizontalAlignment="Left"
      IsEditable ="True"
      Visibility="{Binding Path=IsEditable, Converter={StaticResource VisibilityConverter}}"/>
  <TextBox
      x:Name="RecipientName"
      Text="{Binding ElementName=RecipientID, Path=Text}"
      Margin="6,6,0,6"
      MinWidth="200"
      HorizontalAlignment="Left"
      Style="{StaticResource textBoxInError}"
      Visibility="{Binding Path=IsReadOnly, Converter={StaticResource VisibilityConverter}}"/>
</DockPanel>
汐鸠 2024-10-23 01:14:23

我认为您会发现以这种非常简单的方式创建一个类来扩展 ComboBox 类更加容易和实用:

  1. 重写 Combobox 的 OnSelectionChanged 方法以在允许运行 base.OnSelectionChanged(e) 之前检查属性 IsReadOnly 。

这样您只需将 ComboBox.IsReadOnly 属性设置为 True 即可。无需到处编写大型 XAML...

I think that you will find it much easier and practical to create a class to extend the ComboBox class in this very simple manner:

  1. override the OnSelectionChanged method of the Combobox to check the property IsReadOnly before to allow base.OnSelectionChanged(e) to run.

That way you just have to set ComboBox.IsReadOnly property to True. No big XAML to write everywhere...

雪花飘飘的天空 2024-10-23 01:14:23

下面是一个自定义 ComboBox 子类,它提供了我的场景所需的只读行为:

public class ReadOnlyComboBox : ComboBox
{
    static ReadOnlyComboBox()
    {
        IsDropDownOpenProperty.OverrideMetadata(typeof(ReadOnlyComboBox), new FrameworkPropertyMetadata(
            propertyChangedCallback: delegate { },
            coerceValueCallback: (d, value) =>
            {
                if (((ReadOnlyComboBox)d).IsReadOnly)
                {
                    // Prohibit opening the drop down when read only.
                    return false;
                }

                return value;
            }));

        IsReadOnlyProperty.OverrideMetadata(typeof(ReadOnlyComboBox), new FrameworkPropertyMetadata(
            propertyChangedCallback: (d, e) =>
            {
                // When setting "read only" to false, close the drop down.
                if (e.NewValue is true)
                {
                    ((ReadOnlyComboBox)d).IsDropDownOpen = false;
                }
            }));
    }

    protected override void OnSelectionChanged(SelectionChangedEventArgs e)
    {
        if (IsReadOnly)
        {
            // Disallow changing the selection when read only.
            e.Handled = true;
            return;
        }

        base.OnSelectionChanged(e);
    }
}

关于此方法的要点:

  • 与引入其他 UI 元素的方法不同,不会破坏应用于元素的任何现有样式。
  • 只读时不会破坏输入焦点。您仍然可以使用 Tab 键进入并单击以聚焦此元素。这更容易访问,这是我的场景中所关心的问题。
  • 默认情况下,UI 元素在只读时看起来没有任何不同。如果您需要的话,您将必须应用相关的样式来实现它。

Here is a custom ComboBox subclass that gives the read only behaviour I needed for my scenario:

public class ReadOnlyComboBox : ComboBox
{
    static ReadOnlyComboBox()
    {
        IsDropDownOpenProperty.OverrideMetadata(typeof(ReadOnlyComboBox), new FrameworkPropertyMetadata(
            propertyChangedCallback: delegate { },
            coerceValueCallback: (d, value) =>
            {
                if (((ReadOnlyComboBox)d).IsReadOnly)
                {
                    // Prohibit opening the drop down when read only.
                    return false;
                }

                return value;
            }));

        IsReadOnlyProperty.OverrideMetadata(typeof(ReadOnlyComboBox), new FrameworkPropertyMetadata(
            propertyChangedCallback: (d, e) =>
            {
                // When setting "read only" to false, close the drop down.
                if (e.NewValue is true)
                {
                    ((ReadOnlyComboBox)d).IsDropDownOpen = false;
                }
            }));
    }

    protected override void OnSelectionChanged(SelectionChangedEventArgs e)
    {
        if (IsReadOnly)
        {
            // Disallow changing the selection when read only.
            e.Handled = true;
            return;
        }

        base.OnSelectionChanged(e);
    }
}

Points about this approach:

  • Doesn't break any existing styles applied to the element, unlike an approach that introduces additional UI elements.
  • Doesn't break input focus while read only. You can still tab into and click to focus this element. This is more accessible, which is a concern in my scenario.
  • The UI element doesn't, but default, look any different when read only. If you need that, you would have to apply relevant styles to make it so.
梦纸 2024-10-23 01:14:23

如果 IsEnabled 设置为 false,则 Combobox 值几乎不可读。我发现合适的解决方案是:

  • 组合框和文本框(格式化为只读)位于相同的网格位置
  • 组合框跨越到下一列以获得额外的 15 宽度,因此下拉按钮可见
  • 文本框。IsVisible 绑定到组合框。IsEnabled 具有 bool 可见性转换器。
  • textbox.Text 绑定到combobox.SelectedItem(在我的例子中,它是强类型的,所以我实际上绑定到它的.DisplayText)

If IsEnabled is set to false, Combobox value is nearly not readable. What I found as suitable solution is:

  • combobox and textbox (formated as readonly) are in the same grid position
  • combobox spans to next column to gain additional 15 width so dropdown button is visible
  • textbox.IsVisible is bound to combobox.IsEnabled with bool to visibility converter.
  • textbox.Text is bound to combobox.SelectedItem (in my case it is strongly typed so I actually bound into .DisplayText of it)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文