这里我给出了一个控件的图像,它将显示许多图像的缩略图,用户可以在图像之间滚动。用户可以设置每行显示的图像数量。用户可以设置显示的行数,也可以设置数据绑定等。
我是WPF的新手。所以我只能指导我如何绘制上面的输出。感谢
答案 0 :(得分:2)
据我所知,你需要添加Up,Down,它会用图像滚动ListBox
。 ListBox
已包含带有标准滚动条的ScrollViewer
。我建议我们应该隐藏标准滚动条,并使用导航按钮设置自己。
这些按钮的功能将参考标准ScrollViewer
。要访问ScrollViewer
中的ListBox
,您必须使用以下函数:
public static DependencyObject GetScrollViewer(DependencyObject Object)
{
if (Object is ScrollViewer)
{
return Object;
}
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(Object); i++)
{
var child = VisualTreeHelper.GetChild(Object, i);
var result = GetScrollViewer(child);
if (result == null)
{
continue;
}
else
{
return result;
}
}
return null;
}
在VisualTreeHelper
的帮助下,此函数返回ScrollViewer
类型的对象。
垂直向上导航如下:
scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - 30);
我们为按钮定义一个样式,它将包含箭头形式的Path
。下面是一个带注释的完整示例。
XAML
<Window x:Class="CustomListboxNavHelp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CustomListboxNavHelp"
Title="MainWindow" Height="450" Width="525"
WindowStartupLocation="CenterScreen"
ContentRendered="Window_ContentRendered">
<Window.Resources>
<!-- Style for ListBox -->
<Style x:Key="MyListBoxStyle" TargetType="{x:Type ListBox}">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="ScrollViewer.CanContentScroll" Value="False" />
<Setter Property="HorizontalAlignment" Value="Center" />
<!-- Hidden Scrollbar`s -->
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Hidden" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" />
<!-- DataTemplate for ListBoxItem -->
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Border BorderBrush="Transparent" BorderThickness="1">
<Image Source="{Binding Path=MyImagePath}" Stretch="Fill" Width="100" Height="140" />
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Style for UpButton -->
<Style x:Key="UpButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="ToolTip" Value="Up" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border CornerRadius="0" Background="{TemplateBinding Background}">
<Grid>
<ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Path x:Name="UpButton" SnapsToDevicePixels="True" Width="20" Height="18" Stretch="Fill" Fill="Gray" Data="F1 M 37.8516,35.625L 34.6849,38.7917L 23.6016,50.2708L 23.6016,39.9792L 37.8516,24.9375L 52.1016,39.9792L 52.1016,50.2708L 41.0182,38.7917L 37.8516,35.625 Z "/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="UpButton" Property="Fill" Value="Black" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Style for DownButton -->
<Style x:Key="DownButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="ToolTip" Value="Down" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border CornerRadius="0" Background="{TemplateBinding Background}">
<Grid>
<ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Path x:Name="DownButton" SnapsToDevicePixels="True" Width="20" Height="18" Stretch="Fill" Fill="Gray" Data="F1 M 37.8516,39.5833L 52.1016,24.9375L 52.1016,35.2292L 37.8516,50.2708L 23.6016,35.2292L 23.6016,24.9375L 37.8516,39.5833 Z "/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="DownButton" Property="Fill" Value="Black" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<StackPanel>
<Button Name="UpDirection" Style="{StaticResource UpButtonStyle}" Width="40" Height="30" Click="UpDirection_Click" />
<ListBox Name="MyListBox" Style="{StaticResource MyListBoxStyle}" Width="110" Height="300" />
<Button Name="DownDirection" Style="{StaticResource DownButtonStyle}" Width="40" Height="30" Click="DownDirection_Click" />
</StackPanel>
</Grid>
</Window>
Code behind
public partial class MainWindow : Window
{
private ObservableCollection<ImagesClass> ImagesCollection = new ObservableCollection<ImagesClass>();
public MainWindow()
{
InitializeComponent();
}
private void Window_ContentRendered(object sender, EventArgs e)
{
ImagesCollection.Add(new ImagesClass()
{
MyImagePath = "Cover1.png" // Images must be in resource
});
ImagesCollection.Add(new ImagesClass()
{
MyImagePath = "Cover2.png"
});
ImagesCollection.Add(new ImagesClass()
{
MyImagePath = "Cover3.png"
});
ImagesCollection.Add(new ImagesClass()
{
MyImagePath = "Cover4.png"
});
ImagesCollection.Add(new ImagesClass()
{
MyImagePath = "Cover5.png"
});
ImagesCollection.Add(new ImagesClass()
{
MyImagePath = "Cover6.png"
});
MyListBox.ItemsSource = ImagesCollection;
}
private void UpDirection_Click(object sender, RoutedEventArgs e)
{
NavigationInScrollViewer(MyListBox, "Up", 40);
}
private void DownDirection_Click(object sender, RoutedEventArgs e)
{
NavigationInScrollViewer(MyListBox, "Down", 40);
}
/// <summary>
/// Vertical navigation for ListBox
/// </summary>
/// <param name="myListbox">ListBox</param>
/// <param name="direction">Direction for scrolling</param>
/// <param name="offset">Offset</param>
private void NavigationInScrollViewer(ListBox myListbox, string direction, int offset)
{
ScrollViewer scrollViewer = GetScrollViewer(MyListBox) as ScrollViewer;
if (direction == "Up")
{
if (scrollViewer != null)
{
scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - offset);
}
}
if (direction == "Down")
{
if (scrollViewer != null)
{
scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + offset);
}
}
}
/// <summary>
/// Get ScrollViewer from Control
/// </summary>
/// <param name="Object">Dependency object</param>
/// <returns>ScrollViewer control</returns>
public static DependencyObject GetScrollViewer(DependencyObject Object)
{
if (Object is ScrollViewer)
{
return Object;
}
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(Object); i++)
{
var child = VisualTreeHelper.GetChild(Object, i);
var result = GetScrollViewer(child);
if (result == null)
{
continue;
}
else
{
return result;
}
}
return null;
}
}
/// <summary>
/// Class contain paths to images
/// </summary>
public class ImagesClass
{
private string myImagePath = null;
public string MyImagePath
{
get
{
return myImagePath;
}
set
{
myImagePath = value;
}
}
}
Output
<强> EDIT:
强>
要在单个ListBoxItem
中显示多个图片,您需要更正ItemTemplate
。我建议使用Grid
,因为它是ColumnDefenition
的属性,用于定义项目的列号。
另一件事是你知道这是可取的:
一个ListBoxItem
中显示的最终图像数量。
对于大量图像需要改进的方法,因为它更适合静态显示。
正确ItemTenplate
:
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Border BorderBrush="Transparent" BorderThickness="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Source="{Binding Path=MyImagePathOne}" Grid.Column="0" Stretch="Fill" Width="100" Height="140" />
<Image Source="{Binding Path=MyImagePathTwo}" Grid.Column="1" Stretch="Fill" Width="100" Height="140" />
</Grid>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
ImageClass
public class ImagesClass
{
private string myImagePathOne = null;
public string MyImagePathOne
{
get
{
return myImagePathOne;
}
set
{
myImagePathOne = value;
}
}
private string myImagePathTwo = null;
public string MyImagePathTwo
{
get
{
return myImagePathTwo;
}
set
{
myImagePathTwo = value;
}
}
}
将图像添加到集合中:
ImagesCollection.Add(new ImagesClass()
{
MyImagePathOne = "Cover1.png",
MyImagePathTwo = "Cover2.png"
});
ImagesCollection.Add(new ImagesClass()
{
MyImagePathOne = "Cover3.png",
MyImagePathTwo = "Cover4.png"
});
ImagesCollection.Add(new ImagesClass()
{
MyImagePathOne = "Cover5.png",
MyImagePathTwo = "Cover6.png"
});
Output
如果您肯定需要动态更改图像数量,在这种情况下,您可以执行此操作 - 设置设置属性的集合,例如,只设置单个图像。然后,清理它并将其放在具有任意数量图像的设定值上。
我认为这种方法不是百分之百。如果速度很重要,或者大量图像,则需要优化方法,或者提出另一种方法。
<强> EDIT 2
强>
向上和向下按钮:
<Button Name="Up" Width="150" Height="15" Background="#CDE2FF">
<Button.Content>
<Polygon Points="3.33,0 6.66,6.66, 0,6.66" Fill="#466690" />
</Button.Content>
</Button>
<Button Name="Down" Width="150" Height="15" Background="#CDE2FF" Margin="0,10,0,0">
<Button.Content>
<Polygon Points="0,0 3.33,6.66, 6.66,0" Fill="#466690" />
</Button.Content>
</Button>
Output