在这里,我给出了一个控件的图像,它将显示许多图像的缩略图,用户可以在图像之间滚动。用户可以设置每行显示多少张图像。用户可以设置将显示多少行以及可以进行数据绑定等。
我是 WPF 的新手。所以请指导我如何绘制上面的输出。谢谢
在这里,我给出了一个控件的图像,它将显示许多图像的缩略图,用户可以在图像之间滚动。用户可以设置每行显示多少张图像。用户可以设置将显示多少行以及可以进行数据绑定等。
我是 WPF 的新手。所以请指导我如何绘制上面的输出。谢谢
据我了解,您需要添加向上,向下,这将ListBox
与图像一起滚动。ListBox
已经包含一个ScrollViewer
带有标准滚动条的。我建议我们应该隐藏标准滚动条,并设置导航按钮。
这些按钮的功能将参考标准ScrollViewer
。为了访问ScrollViewer
in 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
箭头形式的 a。下面是一个带有注释的完整示例。
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