我有一个用户控件,它接受一些字符串并根据字符串在我的集合中出现的次数在UI中显示它们。因此,我的集合中包含字符串的次数越多,它在UI中显示的越大,反之亦然。无论如何我的问题是,目前scrollViewer正在显示标签,但我希望所有标签都显示在一个窗口中,无需滚动,也可以缩放以适应整个窗口。任何人都可以协助吗?谢谢!
XAML:
<UserControl x:Class="TagCloudDemo.TagCloudControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:TagCloudDemo="clr-namespace:TagCloudDemo">
<UserControl.Resources>
<TagCloudDemo:WeightToSizeConverter x:Key="WeightToSizeConverter" />
</UserControl.Resources>
<ScrollViewer HorizontalScrollBarVisibility="Auto">
<ItemsControl
ItemsSource="{Binding Path=Tags, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TagCloudDemo:TagCloudControl}}}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}" FontSize="{Binding Path=Weight, Converter={StaticResource WeightToSizeConverter}}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</UserControl>
代码背后:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace TagCloudDemo
{
public partial class TagCloudControl : UserControl
{
public TagCloudControl()
{
InitializeComponent();
}
public IEnumerable<string> Words
{
get { return (IEnumerable<string>)GetValue(WordsProperty); }
set { SetValue(WordsProperty, value); }
}
public static readonly DependencyProperty WordsProperty =
DependencyProperty.Register("Words",
typeof(IEnumerable<string>),
typeof(TagCloudControl),
new UIPropertyMetadata(new List<string>(), WordsChanged));
public IEnumerable<Tag> Tags
{
get { return (IEnumerable<Tag>)GetValue(TagsProperty); }
set { SetValue(TagsProperty, value); }
}
public static readonly DependencyProperty TagsProperty =
DependencyProperty.Register("Tags",
typeof(IEnumerable<Tag>),
typeof(TagCloudControl),
new UIPropertyMetadata(new List<Tag>(), TagsChanged));
private static void WordsChanged(object sender, DependencyPropertyChangedEventArgs e)
{
TagCloudControl tagCloudControl = sender as TagCloudControl;
tagCloudControl.Tags = TagCloudDemo.Tag.CreateTags(tagCloudControl.Words);
}
private static void TagsChanged(object sender, DependencyPropertyChangedEventArgs e)
{
TagCloudControl tagCloudControl = sender as TagCloudControl;
WeightToSizeConverter converter = tagCloudControl.FindResource("WeightToSizeConverter") as WeightToSizeConverter;
if (converter != null && tagCloudControl.Tags != null)
{
converter.MaxWeight = tagCloudControl.Tags.Max(t => t.Weight);
}
}
}
public class WeightToSizeConverter : IValueConverter
{
public int MaxWeight { get; set; }
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
int weight = (int)value;
return 32 * MaxWeight / weight;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion IValueConverter Members
}
}
答案 0 :(得分:1)
使用ViewBox
代替ScrollViewer
来包装您的代码云。
答案 1 :(得分:0)
如果您的目标是像wordle.net产生的那样,那么您需要使用画布并使用一些算法定位每个标记,这将最小化每个标记之间的空间,请参阅Algorithm to implement something like Wordle。这将是一些难以编写的代码。
更简单的解决方案是使用wrappanel并放入视图框。将以下代码添加到您的itemscontrol。这是我见过其他人使用的创建标签云控件并发布其代码的解决方案,例如:Creating a Tag Cloud in Silverlight
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>