2014-11-02 137 views
1

我将一个ItemsControl绑定到名为SwatchThumbnails的可观察集合,该集合将包含数据以生成矩形。矩形可以有1-3个与之相关的颜色,并且在渲染时需要显示多种颜色。我想我明白如何将一种颜色绑定到填充,但我需要一种方法来绑定多达三个,并让它们均匀显示。如何才能做到这一点?如何绑定多个颜色来填充WPF中的矩形?

这是我的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; 
} 

回答

1

要用于其实每个缩略图的背景看起来像一个垂直LinearGradientBrush所以这里最好的选择是LinearGradientBrush,不DrawingBrush这也太复杂(矫枉过正)对于这种情况。您需要一些Colors属性(使用INotifyPropertyChanged)来保存颜色范围。要将其转换为LinearGradientBrush,您需要一个Converter。我知道所有的颜色带应该有相同的高度(和全宽)。幸运的是,LinearGradientBrush中的Offset与整个Height相对(按某种比例),所以我们不需要关于相关Rectangle的实际高度的任何信息。这里是转换器类:

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>型)。

定义你的转换器的一些资源在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"); 
     } 
    } 
    } 
} 
+0

感谢您的支持,并对我的延迟表示歉意。我正在尝试您的解决方案,但矩形行项目给我一个错误。 “属性ItemsTemplate不支持”矩形“类型的值,这对我来说真的很奇怪, – Yecats 2014-11-09 17:36:56

+0

@Yecats是的,这是我愚蠢的错误,请参阅更新的代码 – 2014-11-09 17:40:21

+0

感谢它让我过去错误,但我遇到了麻烦我认为,我已经确认observablecollection有三个项目,当我运行程序时,没有显示任何内容,转换器上的断点从来没有触发,这使我认为绑定可能关闭了吗? – Yecats 2014-11-09 17:57:15

0

据我所知道的最简单的方法是使用一个DrawingBrush代替SolidColorBrush的。

你DrawingBrush形容你用它来填补你的矩形图案(在你的情况,你会用你的三个的SolidColor笔刷绘制DrawingBrush的内容)。 矩形的Fill属性应该绑定到DrawingBrush。

参见如何使用DrawingBrush为矩形填充here的描述。