使用Combobox绘制C#Wpf

问题描述 投票:0回答:1

我需要帮助绘制我的组合框。我想制作一个用于拾取的颜色组合框。我在互联网上找到了一些东西,但没有一个在工作。到目前为止我有这个:

 private void MyComb_DrawItem(object sender, DrawItemEventArgs e)
        {
            Graphics g = e.Graphics;
            System.Drawing.Rectangle rect = e.Bounds;
            ColorConverter converter = new ColorConverter();
             if (e.Index >= 0)
             {
             string n = ((ComboBox)sender).Items[e.Index].ToString();
              System.Drawing.Color c = (System.Drawing.Color)converter.ConvertFromString(n);
                SolidBrush b = new SolidBrush(c);
              g.FillRectangle(b, rect.X + 110, rect.Y + 5,
                  rect.Width - 10, rect.Height - 10);
          }

        }

这是我的drawItem方法

<Grid>
        <ComboBox x:Name="MyComb" HorizontalAlignment="Left" Margin="66,81,0,0" VerticalAlignment="Top" Width="120" />

    </Grid>

这是组合框的定义

Type colorType = typeof(System.Drawing.Color);
            PropertyInfo[] propInfoList = colorType.GetProperties(BindingFlags.Static |
                                                                  BindingFlags.DeclaredOnly | BindingFlags.Public);
            foreach (PropertyInfo c in propInfoList)
            {
                MyComb.Items.Add(c.Name);

            }

在这里,我用颜色名称填充组合框,然后我想根据颜色名称填充真实颜色的combox ..但是我的绘图项方法永远不会被调用。我试图创建一些DrawItem处理程序但是,我的组合框没有这样的东西......然后我读了一些关于设置combobox的DrawMode属性的东西,但我的组合框根本没有那种属性......我正在使用net framework v.4.6.1请有人告诉我,我错过了什么?

非常感谢你

c# wpf combobox
1个回答
1
投票

您遇到的最大问题是您正在尝试使用为Winforms API编写的代码示例,即使您使用的是WPF API。为了将来参考,您需要更加谨慎地识别在线查找的教程和其他资源的上下文,以确保它们实际应用于您的场景。

碰巧,我们已经有很多关于Stack Overflow的相关问题了:

WPF ComboBox as System.Windows.Media.Colors> WPF - Bind ComboBox Item Foreground to Its Value Very simple color picker made of combobox

这些对你都有用,但都是基于这个问题的答案:

How can I list colors in WPF with XAML?

最初只是显示颜色的名称,因此使用XAML中的<ObjectDataProvider/>元素进行了快捷方式。这导致需要在其他问题中使用转换器,将string值或PropertyInfo实例转换为适当的颜色或画笔。

事实上,如果你的代码已经被编写为使用某种类型的MVVM方法,特别是因为你已经编写了代码隐藏来从Colors类型中检索颜色值,或者至少试过(你的问题之一)代码是您正在使用Winforms Color类型而不是WPF Colors类型...再次,在Winforms中工作正常,但WPF API更紧密地遵循代码分析/ FxCop规则,并且命名颜色在Colors类型中),只需坚持下去并提供可绑定的直接视图模型数据结构就有意义了。

在这种方法中,您不是提供项目绘图的过程实现,而是在XAML中提供描述每个项目应该是什么样的声明实现。

这是一个例子......

首先,一些简单的视图模型数据结构:

// Very simple container class
class ColorViewModel
{
    public Brush Brush { get; }
    public string Name { get; }

    public ColorViewModel(Brush brush, string name)
    {
        Brush = brush;
        Name = name;
    }
}

// Main view model, acts as the data context for the window
class MainViewModel : INotifyPropertyChanged
{
    public IReadOnlyList<ColorViewModel> Colors { get; }

    private Brush _selectedColor;
    public Brush SelectedColor
    {
        get { return _selectedColor; }
        set { _UpdateField(ref _selectedColor, value); }
    }

    public MainViewModel()
    {
        Colors = typeof(Colors).GetProperties(BindingFlags.Static | BindingFlags.Public)
            .Select(p => new ColorViewModel(new SolidColorBrush((Color)p.GetValue(null)), p.Name))
            .ToList().AsReadOnly();
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void _UpdateField<T>(ref T field, T newValue, [CallerMemberName] string propertyName = null)
    {
        if (!EqualityComparer<T>.Default.Equals(field, newValue))
        {
            field = newValue;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

有了这些,XAML是直截了当的:

<Window x:Class="TestSO47850587ColorComboBox.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:l="clr-namespace:TestSO47850587ColorComboBox"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">

  <Window.DataContext>
    <l:MainViewModel/>
  </Window.DataContext>

  <StackPanel>
    <ComboBox Width="100" ItemsSource="{Binding Colors}"
              HorizontalAlignment="Left" Grid.IsSharedSizeScope="True"
              SelectedValuePath="Brush" SelectedValue="{Binding SelectedColor}">
      <ComboBox.ItemTemplate>
        <DataTemplate DataType="{x:Type l:ColorViewModel}">
          <Grid>
            <Grid.ColumnDefinitions>
              <ColumnDefinition Width="Auto" SharedSizeGroup="ComboBoxItem"/>
            </Grid.ColumnDefinitions>
            <TextBlock Text="{Binding Name}" Background="{Binding Brush}" HorizontalAlignment="Stretch"/>
          </Grid>
        </DataTemplate>
      </ComboBox.ItemTemplate>
    </ComboBox>

    <Rectangle HorizontalAlignment="Stretch" Height="24" Fill="{Binding SelectedColor}"/>
  </StackPanel>
</Window>

以上显示颜色名称,使用实际颜色作为背景。如果你真正想要的只是一个矩形,那么你可以用<TextBlock/>元素替换<Rectangle/>元素,绑定到它的Fill属性。当然,您可以实现其他视觉效果,例如带边距的矩形。只需根据您的需要配置数据模板即可。

这里的要点是你应该采用定义良好WPF编程的数据绑定方法,并且你绝对不应该将Winforms代码示例误认为是WPF。 :)

© www.soinside.com 2019 - 2024. All rights reserved.