- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要创建格式良好的按钮图 block ,例如 Windows 8 开始页面。是否有任何工具包可用于自定义 ListView,它可能支持平铺 View 或 GridView ,具有一些格式设置,并且可能有一些动画选项。
我尝试创建自己的自定义 ListView ,但这似乎是一项复杂的任务。
最佳答案
我不知道有什么好的免费图 block 控件。 DevExpress有一个好看的商业版本。
如果您指定了确切的要求(即您需要配置哪些属性、什么样的动画……)并且我有时间,我会尝试一下。
编辑:我创建了一个带有 WrapPanel 作为 ItemsPanel 的 ItemsControl。使用 MVVM 模式,根据您的需要和数据对象扩展控件应该不会太困难。 DragDrop 行为部分很难做到——当然还有一些改进的空间。我没有包含图像。
TileControl.xaml:
<UserControl x:Class="WpfApplication1.TileControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:local="clr-namespace:WpfApplication1"
xmlns:beh="clr-namespace:WpfApplication1.Behavior"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.DataContext>
<local:ViewModel />
</UserControl.DataContext>
<UserControl.Resources>
<local:TileTypeToColorConverter x:Key="TileTypeToColorConverter" />
</UserControl.Resources>
<Grid>
<Image Source="/WpfApplication1;component/Themes/background.png" Stretch="UniformToFill" />
<Border x:Name="darkenBorder" Background="Black" Opacity="0.6" />
<ItemsControl ItemsSource="{Binding Tiles}" Background="Transparent" Margin="5">
<i:Interaction.Behaviors>
<beh:ItemsControlDragDropBehavior />
</i:Interaction.Behaviors>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="local:TileModel">
<Button Content="{Binding Text}" Background="{Binding TileType, Converter={StaticResource TileTypeToColorConverter}}"
Command="{Binding ClickCommand}" Width="120" Height="110" Padding="5" RenderTransformOrigin="0.5, 0.5" >
<Button.RenderTransform>
<TransformGroup>
<ScaleTransform />
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Button.RenderTransform>
<Button.Template>
<ControlTemplate TargetType="Button">
<Border Padding="5" Background="Transparent">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border x:Name="tileBackground" Grid.RowSpan="2" Background="{TemplateBinding Background}" Opacity="0.9" />
<Image Source="{Binding Image}" HorizontalAlignment="Center" VerticalAlignment="Bottom" Height="50" />
<ContentPresenter TextElement.Foreground="White" Grid.Row="1" HorizontalAlignment="Center" Margin="3,10" />
</Grid>
</Border>
</ControlTemplate>
</Button.Template>
<Button.Resources>
<ElasticEase x:Key="easeOutBounce" EasingMode="EaseOut" Springiness="6" Oscillations="4" />
</Button.Resources>
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard Duration="00:00:00.05" AutoReverse="True">
<DoubleAnimation To="0.1" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"/>
<DoubleAnimation To="0.1" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" From="0.1" To="1.0" EasingFunction="{StaticResource easeOutBounce}" />
<DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" From="0.1" To="1.0" EasingFunction="{StaticResource easeOutBounce}" />
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="0.1" To="1.0" EasingFunction="{StaticResource easeOutBounce}" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</UserControl>
ViewModel、TileModel、TileType、ActionCommand:
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Input;
using System.Windows.Media.Imaging;
namespace WpfApplication1
{
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private ObservableCollection<TileModel> _tiles;
public ObservableCollection<TileModel> Tiles { get { return _tiles; } set { _tiles = value; OnPropertyChanged("Tiles"); } }
public ViewModel()
{
Tiles= new ObservableCollection<TileModel>()
{
new TileModel() { Text = "Facebook", Image = Properties.Resources.Facebook.ToBitmapImage(), TileType = TileType.Website },
new TileModel() { Text = "Skype", Image = Properties.Resources.Skype.ToBitmapImage(), TileType = TileType.Application },
new TileModel() { Text = "Ask.com", Image = Properties.Resources.AskCom.ToBitmapImage(), TileType = TileType.Website },
new TileModel() { Text = "Amazon", Image = Properties.Resources.Amazon.ToBitmapImage(), TileType = TileType.Website },
new TileModel() { Text = "Evernote", Image = Properties.Resources.Evernote.ToBitmapImage(), TileType = TileType.Application },
new TileModel() { Text = "Twitter", Image = Properties.Resources.Twitter.ToBitmapImage(), TileType = TileType.Website },
new TileModel() { Text = "Internet Explorer", Image = Properties.Resources.InterneExplorer.ToBitmapImage(), TileType = TileType.Browser },
new TileModel() { Text = "Android", Image = Properties.Resources.Android.ToBitmapImage(), TileType = TileType.Application },
new TileModel() { Text = "Winamp", Image = Properties.Resources.Winamp.ToBitmapImage(), TileType = TileType.Application },
new TileModel() { Text = "YouTube", Image = Properties.Resources.YouTube.ToBitmapImage(), TileType = TileType.Website },
};
}
}
public class TileModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private string _text;
public string Text { get { return _text; } set { _text = value; OnPropertyChanged("Text"); } }
private BitmapSource _image;
public BitmapSource Image { get { return _image; } set { _image = value; OnPropertyChanged("Image"); } }
private TileType _tileType;
public TileType TileType { get { return _tileType; } set { _tileType = value; OnPropertyChanged("TileType"); } }
public ICommand ClickCommand { get; private set; }
public TileModel()
{
ClickCommand = new ActionCommand(Click);
}
private void Click()
{
// execute appropriate action
}
}
public enum TileType
{
Browser,
Website,
Application
}
public class ActionCommand : ICommand
{
public event EventHandler CanExecuteChanged;
private Action _action;
public ActionCommand(Action action)
{
_action = action;
}
public bool CanExecute(object parameter) { return true; }
public void Execute(object parameter)
{
if (_action != null)
_action();
}
}
}
ItemsControlDragDropBehavior:
using System;
using System.Collections;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Interactivity;
using System.Windows.Media;
namespace WpfApplication1.Behavior
{
public class ItemsControlDragDropBehavior : Behavior<ItemsControl>
{
private bool _isMouseDown;
private bool _isDragging;
private Point _dragStartPosition;
private UIElement _dragItem;
private UIElement _dragContainer;
private IDataObject _dataObject;
private int _currentDropIndex;
private Point _lastCheckPoint;
protected override void OnAttached()
{
this.AssociatedObject.AllowDrop = true;
this.AssociatedObject.PreviewMouseLeftButtonDown += AssociatedObject_PreviewMouseLeftButtonDown;
this.AssociatedObject.PreviewMouseMove += AssociatedObject_PreviewMouseMove;
this.AssociatedObject.PreviewDragOver += AssociatedObject_PreviewDragOver;
this.AssociatedObject.PreviewDrop += AssociatedObject_PreviewDrop;
this.AssociatedObject.PreviewMouseLeftButtonUp += AssociatedObject_PreviewMouseLeftButtonUp;
base.OnAttached();
}
void AssociatedObject_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
ItemsControl itemsControl = (ItemsControl)sender;
Point p = e.GetPosition(itemsControl);
object data = itemsControl.GetDataObjectFromPoint(p);
_dataObject = data != null ? new DataObject(data.GetType(), data) : null;
_dragContainer = itemsControl.GetItemContainerFromPoint(p);
if (_dragContainer != null)
_dragItem = GetItemFromContainer(_dragContainer);
if (data != null)
{
_isMouseDown = true;
_dragStartPosition = p;
}
}
void AssociatedObject_PreviewMouseMove(object sender, MouseEventArgs e)
{
if (_isMouseDown)
{
ItemsControl itemsControl = (ItemsControl)sender;
Point currentPosition = e.GetPosition(itemsControl);
if ((_isDragging == false) && (Math.Abs(currentPosition.X - _dragStartPosition.X) > SystemParameters.MinimumHorizontalDragDistance) ||
(Math.Abs(currentPosition.Y - _dragStartPosition.Y) > SystemParameters.MinimumVerticalDragDistance))
{
DragStarted(e.GetPosition(itemsControl));
}
e.Handled = true;
}
}
void AssociatedObject_PreviewDragOver(object sender, DragEventArgs e)
{
UpdateDropIndex(e.GetPosition(this.AssociatedObject));
}
void AssociatedObject_PreviewDrop(object sender, DragEventArgs e)
{
UpdateDropIndex(e.GetPosition(this.AssociatedObject));
}
void AssociatedObject_PreviewMouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
_isMouseDown = false;
}
private void DragStarted(Point p)
{
if (!_isDragging)
{
_isDragging = true;
if (_dragContainer != null)
_dragContainer.Opacity = 0.3;
_currentDropIndex = FindDropIndex(p);
DragDropEffects e = DragDrop.DoDragDrop(this.AssociatedObject, _dataObject, DragDropEffects.Copy | DragDropEffects.Move);
ResetState();
}
}
private void ResetState()
{
if (_dragContainer != null)
_dragContainer.Opacity = 1.0;
_isMouseDown = false;
_isDragging = false;
_dataObject = null;
_dragItem = null;
_dragContainer = null;
_currentDropIndex = -1;
}
private void UpdateDropIndex(Point p)
{
if ((_lastCheckPoint - p).Length > SystemParameters.MinimumHorizontalDragDistance) // prevent too frequent call
{
int dropIndex = FindDropIndex(p);
if (dropIndex != _currentDropIndex && dropIndex > -1)
{
this.AssociatedObject.RemoveItem(_dataObject);
this.AssociatedObject.AddItem(_dataObject, dropIndex);
_currentDropIndex = dropIndex;
}
_lastCheckPoint = p;
}
}
private int FindDropIndex(Point p)
{
ItemsControl itemsControl = this.AssociatedObject;
UIElement dropTargetContainer = null;
dropTargetContainer = itemsControl.GetItemContainerFromPoint(p);
int index = -1;
if (dropTargetContainer != null)
{
index = itemsControl.ItemContainerGenerator.IndexFromContainer(dropTargetContainer);
if (!IsPointInTopHalf(p))
index = index++; // in second half of item, add after
}
else if (IsPointAfterAllItems(itemsControl, p))
{
// still within itemscontrol, but after all items
index = itemsControl.Items.Count - 1;
}
return index;
}
public bool IsPointInTopHalf(Point p)
{
ItemsControl itemsControl = this.AssociatedObject;
bool isInTopHalf = false;
UIElement selectedItemContainer = itemsControl.GetItemContainerFromPoint(p);
Point relativePosition = Mouse.GetPosition(selectedItemContainer);
if (IsItemControlOrientationHorizontal())
isInTopHalf = relativePosition.X < ((FrameworkElement)selectedItemContainer).ActualWidth / 2;
else
isInTopHalf = relativePosition.Y < ((FrameworkElement)selectedItemContainer).ActualHeight / 2;
return isInTopHalf;
}
private bool IsItemControlOrientationHorizontal()
{
bool isHorizontal = false;
Panel panel = GetItemsPanel();
if (panel is WrapPanel)
isHorizontal = ((WrapPanel)panel).Orientation == Orientation.Horizontal;
else if (panel is StackPanel)
isHorizontal = ((StackPanel)panel).Orientation == Orientation.Horizontal;
return isHorizontal;
}
private UIElement GetItemFromContainer(UIElement container)
{
UIElement item = null;
if (container != null)
item = VisualTreeHelper.GetChild(container, 0) as UIElement;
return item;
}
private Panel GetItemsPanel()
{
ItemsPresenter itemsPresenter = GetVisualChild<ItemsPresenter>(this.AssociatedObject);
Panel itemsPanel = VisualTreeHelper.GetChild(itemsPresenter, 0) as Panel;
return itemsPanel;
}
private static T GetVisualChild<T>(DependencyObject parent) where T : Visual
{
T child = default(T);
int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < numVisuals; i++)
{
Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
child = v as T;
if (child == null)
{
child = GetVisualChild<T>(v);
}
if (child != null)
{
break;
}
}
return child;
}
/// still needs some work
private static bool IsPointAfterAllItems(ItemsControl itemsControl, Point point)
{
bool isAfter = false;
UIElement target = itemsControl.GetLastItemContainer();
Point targetPos = target.TransformToAncestor(itemsControl).Transform(new Point(0, 0));
Point relativeToTarget = new Point(point.X - targetPos.X, point.Y - targetPos.Y);
if (relativeToTarget.X >= 0 && relativeToTarget.Y >= 0)
{
var bounds = VisualTreeHelper.GetDescendantBounds(target);
isAfter = !bounds.Contains(relativeToTarget);
}
return isAfter;
}
}
public static class ItemsControlExtensions
{
public static object GetDataObjectFromPoint(this ItemsControl itemsControl, Point p)
{
UIElement element = itemsControl.InputHitTest(p) as UIElement;
while (element != null)
{
if (element == itemsControl)
return null;
object data = itemsControl.ItemContainerGenerator.ItemFromContainer(element);
if (data != DependencyProperty.UnsetValue)
return data;
else
element = VisualTreeHelper.GetParent(element) as UIElement;
}
return null;
}
public static UIElement GetItemContainerFromPoint(this ItemsControl itemsControl, Point p)
{
UIElement element = itemsControl.InputHitTest(p) as UIElement;
while (element != null)
{
object data = itemsControl.ItemContainerGenerator.ItemFromContainer(element);
if (data != DependencyProperty.UnsetValue)
return element;
else
element = VisualTreeHelper.GetParent(element) as UIElement;
}
return element;
}
public static UIElement GetLastItemContainer(this ItemsControl itemsControl)
{
UIElement container = null;
if (itemsControl.HasItems)
container = itemsControl.GetItemContainerAtIndex(itemsControl.Items.Count - 1);
return container;
}
public static UIElement GetItemContainerAtIndex(this ItemsControl itemsControl, int index)
{
UIElement container = null;
if (itemsControl != null && itemsControl.Items.Count > index && itemsControl.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
container = itemsControl.ItemContainerGenerator.ContainerFromIndex(index) as UIElement;
else
container = itemsControl;
return container;
}
public static void AddItem(this ItemsControl itemsControl, IDataObject item, int insertIndex)
{
if (itemsControl.ItemsSource != null)
{
foreach (string format in item.GetFormats())
{
object data = item.GetData(format);
IList iList = itemsControl.ItemsSource as IList;
if (iList != null)
iList.Insert(insertIndex, data);
else
{
Type type = itemsControl.ItemsSource.GetType();
Type genericList = type.GetInterface("IList`1");
if (genericList != null)
type.GetMethod("Insert").Invoke(itemsControl.ItemsSource, new object[] { insertIndex, data });
}
}
}
else
itemsControl.Items.Insert(insertIndex, item);
}
public static void RemoveItem(this ItemsControl itemsControl, IDataObject itemToRemove)
{
if (itemToRemove != null)
{
foreach (string format in itemToRemove.GetFormats())
{
object data = itemToRemove.GetData(format);
int index = itemsControl.Items.IndexOf(data);
if (index > -1)
itemsControl.RemoveItemAt(index);
}
}
}
public static void RemoveItemAt(this ItemsControl itemsControl, int removeIndex)
{
if (removeIndex != -1 && removeIndex < itemsControl.Items.Count)
{
if (itemsControl.ItemsSource != null)
{
IList iList = itemsControl.ItemsSource as IList;
if (iList != null)
{
iList.RemoveAt(removeIndex);
}
else
{
Type type = itemsControl.ItemsSource.GetType();
Type genericList = type.GetInterface("IList`1");
if (genericList != null)
type.GetMethod("RemoveAt").Invoke(itemsControl.ItemsSource, new object[] { removeIndex });
}
}
else
itemsControl.Items.RemoveAt(removeIndex);
}
}
}
}
TileTypeToColorConverter:
public class TileTypeToColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
SolidColorBrush brush = new SolidColorBrush();
TileType type = (TileType)value;
switch (type)
{
case TileType.Browser: brush.Color = Colors.Maroon; break;
case TileType.Application: brush.Color = Colors.DodgerBlue; break;
case TileType.Website: brush.Color = Colors.DarkGoldenrod; break;
}
return brush;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
关于用于平铺 ListView 的 WPF 工具包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15652597/
鉴于此 export const slice = createSlice({ name: 'reducer', initialState: { }, reducers:
当创建新图表并添加系列(例如 ColumnSeries)和数据时,列将呈现为淡入动画类型,并在屏幕上绘制图表后瞬间出现。 有什么办法可以阻止这个动画的发生吗?或者,是否有办法强制图表在渲染之前完成动画
我正在尝试从 Java 的 JDK 导入 tools.jar,但每当我尝试创建 newInstance 时,都会收到 InstantiationException来自图书馆的类(class)。 到目前
我正在寻找 JavaScript RIA 工具包。我的要求是:漂亮的外观、免费的许可证和健全的 API。有什么想法吗? 这就是我到目前为止所发现的: ExtJS 专业人士 完美的外观 很多小部件 支持
jsPlumb工具包是否可以根据要绘制和连接的对象的数量和类型动态定位内容。我的意思是目前example他们给出的方法是,使用 css 来定位每个节点,当我们动态生成可视化时,这不是一个好的选择,因为
我正在 Linux 中创建磁盘分析器。我想知道哪个 Python 工具包可以帮助我使用 GUI。我目前正在尝试 Tkinter 有更好的东西吗? 最佳答案 “更好”是主观的。我很乐意提出我的意见,即没
我们正在构建一个调查网络应用程序,它允许用户在离线时向调查添加新记录,并在浏览器重新连接到服务器时上传。 我们已经确定这将需要离线存储,因此 google gears 似乎是一个显而易见的选择(我们知
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在寻找可以在 Linux 系统上使用 C++ 语言的 SOAP 工具包。我查看了 AXIS2C,但发现它的文档很少。不幸的是,gSoap 需要许可证,所以还有其他的吗? 最佳答案 我用于 C++
我只是想掌握我可以从中构建的 OpenGL,所以我正在寻找的只是构建 Windows 等的基本知识。我在阅读教程时注意到的一件事就是它似乎就像很多信息已经过时了 - 例如很多教程(其中许多是几年前写的
有谁知道如何在 Silverlight 工具包的 TreeView 中实现拖放? 我看到了 Silverlight 的拖放管理器,但据说您可以在要拖放的项目周围放置容器,但我想知道如何在另一个 Tre
已结束。此问题不符合 Stack Overflow guidelines .它目前不接受答案。 我们不允许提出有关书籍、工具、软件库等方面的建议的问题。您可以编辑问题,以便用事实和引用来回答它。 关闭
我有一个有 6 列的 DataGrid,每列都是一个 RadioButton,以便用户可以选择 1 in 6 选项。大约有100行。我用 6 个 bool 数据成员创建了一个自定义类,然后将数据网格与
从我发现的一个 Silverlight 论坛页面,我的印象是在后面的代码中创建的 ChildWindow 会选择页面其余部分的主题;只有当您从 ChildWindow 继承时,情况才不再如此。 出于某
我正在使用 WPF 工具包 AutoCompleteBox,它的 itemsSource 是一个包含数百万个对象的列表。 AutoCompleteBox 是否用于搜索后台线程,如果没有,我该如何实现。
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?将问题更新为 on-topic对于堆栈溢出。 8年前关闭。 Improve this qu
这个问题已经有答案了: What is the difference between a framework and a library? [closed] (22 个回答) 已关闭 7 年前。 框架
我的问题很简单,我想通过一个简单的例子得到清晰的答案。 API、工具包、框架和库之间的主要区别是什么? 最佳答案 我更喜欢以下内容: API 是如何使用应用程序的抽象描述。例如,API可以描述聊天服务
我有一个 C# 应用程序。目前所有模块都是用 .NET 2 编写的,并且它使用一些具有 Linux 端口的可执行文件。所以我想知道我应该在 Windows 和 MacOS 上使用什么工具包才能在两者上
这是我非常简单的 Accordion XAML :- 如果我非常快地点击 Accordion 项目几次,我会得到这个异常:- AccessViolation
我是一名优秀的程序员,十分优秀!