[英]C# Wpf drawing with Combobox
我需要在组合框中进行绘图的帮助。 我想选一个颜色组合框。 我在互联网上找到了一些东西,但是都没有用。 到目前为止,我有这个:
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处理程序,但是,我的组合框没有这样的东西。。。然后,我读了一些有关设置组合框的DrawMode属性的信息,但是我的组合框根本没有那种属性。 v.4.6.1谁能告诉我,我想念什么?
非常感谢你
您遇到的最大问题是,即使您使用的是WPF API,也要尝试使用为Winforms API编写的代码示例。 为了将来参考,您确实需要更加谨慎地标识在网上找到的教程和其他资源的上下文,以确保它们确实适用于您的方案。
碰巧的是,我们在堆栈溢出方面已经有许多相关问题:
WPF ComboBox作为System.Windows.Media.Colors >
WPF-将ComboBox项绑定到其值的前景
由组合框制成的非常简单的颜色选择器
这些都可能对您有用,但都是基于此问题的答案:
最初只用于显示颜色名称 ,因此使用XAML中的<ObjectDataProvider/>
元素进行了捷径。 这导致需要在其他问题中使用转换器,以将string
值或PropertyInfo
实例转换为适当的颜色或画笔。
实际上,如果您的代码已经被编写为使用某种类型的MVVM方法,尤其是因为您已经编写了代码以从Colors
类型中检索颜色值,或者至少尝试这样做(您的问题之一,代码是您使用的是Winforms Color
类型而不是WPF Colors
类型……同样,在Winforms中可以正常工作,但是WPF API更严格地遵循Code Analysis / 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。 :)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.