我将ItemsControl绑定到名为SwatchThumbnails的可观察集合,该集合将包含数据以生成矩形。矩形可以有1-3种与之关联的颜色,并且在渲染时需要显示多种颜色。我想我理解如何只将一种颜色绑定到填充,但我需要一种方法来绑定三个并让它们均匀显示。怎么办呢?
这是我的XAML:
<ScrollViewer x:Name="sv_Thumbnails" Grid.ColumnSpan="2" Grid.Row="1" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Auto">
<ItemsControl x:Name="ug_Thumbnails" ItemsSource="{Binding SwatchThumbnails, ElementName=mainWindow}">
<ItemsControl.ItemsPanel >
<ItemsPanelTemplate>
<UniformGrid Columns="6" RenderTransformOrigin="0,0.5" Cursor="Hand">
<Rectangle Width="50" Height="50" Fill="{Binding Color}" Margin="0 0 5 0" />
</UniformGrid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
我最初是通过C#代码将矩形形状插入UniformGrid,所以我有原始代码,用于分割颜色。基本上,这是我生成矩形的原始代码:
System.Windows.Shapes.Rectangle swatch = new System.Windows.Shapes.Rectangle();
swatch.Width = 50;
swatch.Height = 50;
swatch.Margin = new Thickness(0, 5, 5, 0);
swatch.StrokeThickness = 1;
swatch.Stroke = System.Windows.Media.Brushes.Gray;
swatch.Name = "s_" + _name.ToString();
double groupsize = 100 / _colors.Count();
DrawingBrush blackBrush = new DrawingBrush();
DrawingGroup checkersDrawingGroup = new DrawingGroup();
List<SolidColorBrush> brushes = _colors;
double location = 0;
for (int i = 0; i < _colors.Count(); i++)
{
GeometryDrawing drawing = new GeometryDrawing(brushes[i], null,
new RectangleGeometry(new Rect(0, location, groupsize, groupsize)));
checkersDrawingGroup.Children.Add(drawing);
location += groupsize;
}
blackBrush.Drawing = checkersDrawingGroup;
swatch.Fill = blackBrush;
swatch.MouseUp += new MouseButtonEventHandler(loadSwatchResources);
最后,这是我的可观察集合和样本缩略图定义。
private ObservableCollection<SwatchThumbnail> swatchThumbnails = new ObservableCollection<SwatchThumbnail>();
public ObservableCollection<SwatchThumbnail> SwatchThumbnails
{
get { return swatchThumbnails; }
set { swatchThumbnails = value; }
}
public class SwatchThumbnail : INotifyPropertyChanged
{
public string name { get; set; }
public List<Color> colors { get; set; }
public bool selected { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
}
答案 0 :(得分:2)
您希望每个缩略图的背景实际上看起来像一个垂直LinearGradientBrush
,因此这里的最佳选择是LinearGradientBrush
,而不是DrawingBrush
这对于这种情况来说过于复杂(并且过度杀伤) 。您需要一些Colors
属性(实现了INotifyPropertyChanged),其中包含Colors范围。要将其转换为LinearGradientBrush
,您需要Converter
。据我所知,所有色带应具有相等的高度(和全宽)。幸运的是,LinearGradientBrush中的Offset
与整个高度相对(以某种比例),因此我们不需要任何关于相关矩形的实际高度的信息。这是Converter类:
public class ColorsToLinearGradientBrushConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter,
CultureInfo culture){
var colors = (List<Color>) value;
var brush = new LinearGradientBrush(){ StartPoint = new Point(),
EndPoint = new Point(0,1)};
var w = 1d / colors.Count;
for(var i = 0; i < colors.Count - 1; i++){
var offset = w * (i+1);
var stop1 = new GradientStop(colors[i], offset);
var stop2 = new GradientStop(colors[i+1], offset);
brush.GradientStops.Add(stop1);
brush.GradientStops.Add(stop2);
}
return brush;
}
//this way back is not needed (bind OneWay)
public object ConvertBack(object value Type targetType, object parameter,
CultureInfo culture){
throw new NotImplementedException();
}
}
请注意,Colors
属性的类型应为List<Color>
(您的原始属性的类型为List<SolidColorBrush>
)。
将您的Converter定义为XAML中的一些资源,并将其正常用于绑定(我希望您知道这一点)。这是XAML代码:
<ScrollViewer x:Name="sv_Thumbnails" Grid.ColumnSpan="2" Grid.Row="1"
VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Auto">
<ScrollViewer.Resources>
<local:ColorsToLinearGradientBrushConverter x:Key="brushConverter"/>
</ScrollViewer.Resources>
<ItemsControl x:Name="ug_Thumbnails" ItemsSource="{Binding SwatchThumbnails,
ElementName=mainWindow}">
<!--ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="6" RenderTransformOrigin="0,0.5" Cursor="Hand">
</UniformGrid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel-->
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Width="50" Height="50" Fill="{Binding Colors,
Converter={StaticResource brushConverter}}"
Margin="0 0 5 0" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
请注意,您必须在此使用一些ItemTemplate
,原始XAML只有ItemsPanel
,它会更改项目的整个容器。如果这是您想要的,只需正常指定该面板,但请记住它只与 如何安排和布局 项目相关。这意味着我们不能仅仅根据它来为每个项目绑定背景。
更新 :我认为您已正确实施SwatchThumbnail
。但看起来你没有。因此,请尝试以下实现,看看它是否有效:
public class SwatchThumbnail : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string prop){
var handler = PropertyChanged;
if(handler != null) handler(this, new PropertyChangedEventArgs(prop));
}
string _name;
public string name {
get { return _name;}
set {
if(_name != value) {
_name = value;
OnPropertyChanged("name");
}
}
}
List<SolidColorBrush> _colors;
public List<SolidColorBrush> colors {
get {
return _colors;
}
set {
_colors = value;
OnPropertyChanged("colors");
}
}
bool _selected;
public bool selected {
get {
return selected;
}
set {
if(_selected != value){
_selected = value;
OnPropertyChanged("selected");
}
}
}
}
答案 1 :(得分:0)
据我所知,最简单的方法是使用DrawingBrush
代替SolidColorBrush
。
您的DrawingBrush将描述用于填充矩形的图案(在您的情况下,您将使用三个SolidColor画笔来绘制DrawingBrush的内容)。
然后,矩形的Fill
属性应绑定到DrawingBrush。
请参阅有关如何将DrawingBrush用作矩形填充的说明here。