ここでは、多くの画像のサムネイルを表示し、ユーザーが画像間をスクロールできるコントロールの画像を提供しています。ユーザーは、1 行に表示する画像の数を設定できます。ユーザーは、表示する行数を設定したり、データバインドなどを行うことができます。
私はWPFが初めてなので、上記のように出力を描画する方法を教えてください。ありがとう
ここでは、多くの画像のサムネイルを表示し、ユーザーが画像間をスクロールできるコントロールの画像を提供しています。ユーザーは、1 行に表示する画像の数を設定できます。ユーザーは、表示する行数を設定したり、データバインドなどを行うことができます。
私はWPFが初めてなので、上記のように出力を描画する方法を教えてください。ありがとう
私が理解しているように、画像をスクロールする上、下を追加する必要がありListBox
ます。には、標準のスクロール バー付きの がListBox
既に含まれています。ScrollViewer
標準のスクロール バーを非表示にして、ナビゲーション ボタンを設定することをお勧めします。
これらのボタンの機能は、標準を参照しますScrollViewer
。in にアクセスするに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
、 type のオブジェクトを返します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:
複数の画像を 1 つの で表示するには、ListBoxItem
を修正する必要がありますItemTemplate
。アイテムの列番号を定義するためGrid
の のプロパティであるため、を使用することをお勧めします。ColumnDefenition
もう1つのことは、それが望ましいことを知っているということです:
1 つの に表示される画像の最終的な数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
この場合から、画像の数を動的に変更する必要が確実にある場合は、これを行うことができます。たとえば、単一の画像のみなど、プロパティが設定されているコレクションを設定します。次に、それをきれいにして、任意の数の画像で設定値に配置します。
この方法は、このアプローチでは 100% ではないと思います。速度が重要な場合、または画像の数が多い場合は、方法を最適化するか、別の方法を考え出す必要があります。
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