This is what i have so far:
<dxe:ComboBoxEdit Name="cboUserCustomReports"
Width="300" Height="Auto"
Margin="0,5,0,5"
ItemsSource="{Binding Path=UserReportProfileList,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"
EditValue="{Binding Path=UserReportProfileID,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
ValueMember="UserReportProfileID"
DisplayMember="ReportName"
PopupClosed="cboUserCustomReports_PopupClosed">
<dxe:ComboBoxEdit.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="{Binding ReportName, Mode=Default}"
VerticalAlignment="Stretch" HorizontalAlignment="Left"/>
<Button Name="btnDelete"
Grid.Column="1"
Width="20" Height="20"
VerticalAlignment="Center" HorizontalAlignment="Right"
Click="btnDelete_Click">
<Button.Template>
<ControlTemplate>
<Image Source="/RMSCommon;component/Resources/Delete.ico"></Image>
</ControlTemplate>
</Button.Template>
</Button>
</Grid>
</DataTemplate>
</dxe:ComboBoxEdit.ItemTemplate>
</dxe:ComboBoxEdit>
First, i want the two columns to be stand alone. The user must be able to select or delete the item.
Second, i would like to make my button in the ItemTemplate to be click-able.
What do i need to add to get this behavior?
This is what it looks like at the moment:
Click
I assume, that your button is clickable, and you want to know how to process the click event. Right?
For the click-handler, add the following code:
private void btnDelete_Click(object sender, RoutedEventArgs e) {
FrameworkElement fe = sender as FrameworkElement;
if(null == fe){
return;
}
UserReportProfile userReportProfile = fe.DataContext as UserReportProfile;
if (null == userReportProfile) {
return;
}
// Do here your deletion-operation
}
I assumed that your item-class is named UserReportProfile. Otherwise, change the declared type accordingly.
Layout
For the alignment, add the following declaration to your ComboBox:
HorizontalContentAlignment="Stretch"
This gives your DataTemplate-Grid the full width and you can layout then your items as you desire.
<dxe:ComboBoxEdit Name="cboUserCustomReports"
HorizontalContentAlignment="Stretch"
Width="300" Height="Auto"
Margin="0,5,0,5"
...>
Your question is not clear enough. But I guess you want to vertically align the text and images in your combobox. If so, then all you need to do this:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
And I think your items are already clickable!
Related
I have a particular layout behavior in mind, and I want to see if anyone can come up with a simple way of doing this before I try to write a custom panel or something. Take a look at this animation I manually put together:
There is an element of fixed width to the far left (the rectangle), and then a second element that is centered- not within the remaining space, but relative to the entire container. As the container shrinks, the centered element stays centered until the left element gets too close. Instead of staying directly in the middle, the "centered" element now stays as close to the center as possible without overlapping. This is the behavior I want.
Using a Grid, I can do something like this:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Border Width="100" Background="Green"/>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Grid.ColumnSpan="2" FontSize="24" Margin="2, 0">Centered Text</TextBlock>
</Grid>
Which puts everything in the right place, but the TextBlock will start overlapping with the Border instead of moving further right.
So any idea how I can get this to do what I want?
Give this a try:
Name of Window x:Name="window1"
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Border x:Name="border1" Width="100" Background="Green"/>
<TextBlock x:Name="textBlock1" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="24" Grid.ColumnSpan="2">Centered Text</TextBlock>
</Grid>
SizeChanged event
private void Window1_SizeChanged(object sender, SizeChangedEventArgs e) {
if(( ( window1.Width / 2 ) - ( textBlock1.ActualWidth / 2 ) - border1.Width - ( SystemParameters.ResizeFrameVerticalBorderWidth * 2 ) ) <= 0) {
Grid.SetColumn(textBlock1, 1);
textBlock1.HorizontalAlignment = HorizontalAlignment.Left;
} else {
Grid.SetColumn(textBlock1, 0);
textBlock1.HorizontalAlignment = HorizontalAlignment.Center;
}
}
My goal is simpel, however i can't figure it out. Sorry for the Titel but couldn't come up with a better explanation...
I have usercontrol with an label that display's the current time (hooked up to a timer with 1 second interval). The label is the width of its parent and the text is aligned in the center. The format is DateTime.ToString("HH : mm : ss"), the FontFamily and size can be adjusted by the user. So far nothing strange... But, the text is aligned centered so when time is lets say 12:34:02 the pixel width different than 12:34:11. (of course depending on the font) This causes the label jump (because it auto centers itself)
The code below is an example of it. the canvas is used to draw stuff on it and the viewbox is used so it autosizes itself in his parent.
Code:
<Grid>
<Viewbox>
<Canvas Name="canv" Height="300" Width="300">
<StackPanel Name="stckpnlDateTime">
<Label Name="lblDateOrText"
Grid.Column="0"
Grid.Row="0"
Content = "------"
FontSize="25"
Foreground="GhostWhite"
HorizontalContentAlignment="Center"
VerticalAlignment="Bottom"
FontFamily="Arial"
Width="Auto"/>
<Label Name="lblTime"
Grid.Column="0"
Grid.Row="1"
Content = "-- : -- : --"
FontSize="25"
Foreground="GhostWhite"
HorizontalContentAlignment="Center"
VerticalAlignment="Top"
FontFamily="DS-Digital"
Width="Auto"/>
</StackPanel>
</Canvas>
</Viewbox>
</Grid>
Private Sub SystemTime_Tick(sender As Object, e As EventArgs) Handles tmrSystemTime.Tick
lblTime.Content = Now.ToString("HH : mm : ss")
End Sub
So i tried a different approach, great a grid with 10 columns and 8 labels, one for each char, and stretch the labels to its parent (cell). This works and keeps the chars on a fixed position. But the width of last column is smaller then the rest... In this image you can see hat i mean, the second purple column is what i mean. Example alignment
Code:
<UserControl.Resources>
<Style x:Key="LabelStyle" TargetType="Label">
<Setter Property="Foreground" Value="White" />
<Setter Property="FontFamily" Value="DS-Digital" />
<Setter Property="FontSize" Value="40"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="HorizontalContentAlignment" Value="Right"/>
<Setter Property="Background" Value="Green" />
</Style>
</UserControl.Resources>
<Grid HorizontalAlignment="Stretch">
<Viewbox HorizontalAlignment="Stretch">
<Canvas Name="canv" Height="300" Width="300" HorizontalAlignment="Stretch">
<StackPanel Name="stckpnlDateTime" HorizontalAlignment="Stretch">
<Label Name="lblDateOrText"
Grid.Column="0"
Grid.Row="0"
Content = ""
FontSize="25"
Foreground="GhostWhite"
HorizontalContentAlignment="Center"
VerticalAlignment="Bottom"
FontFamily="Arial"
Width="Auto"/>
<Grid Name="GridTimeLabel" HorizontalAlignment="Stretch" Width="Auto" Grid.Column="0" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Label Background="Purple" Grid.Column="0" Grid.Row="0"/>
<Label Name="lblTime1" Grid.Column="1" Grid.Row="0" Style="{StaticResource LabelStyle}" Content="-"/>
<Label Name="lblTime2" Grid.Column="2" Grid.Row="0" Style="{StaticResource LabelStyle}" Content="-"/>
<Label Name="lblTime3" Grid.Column="3" Grid.Row="0" Style="{StaticResource LabelStyle}" Content=":"/>
<Label Name="lblTime4" Grid.Column="4" Grid.Row="0" Style="{StaticResource LabelStyle}" Content="-"/>
<Label Name="lblTime5" Grid.Column="5" Grid.Row="0" Style="{StaticResource LabelStyle}" Content="-"/>
<Label Name="lblTime6" Grid.Column="6" Grid.Row="0" Style="{StaticResource LabelStyle}" Content=":"/>
<Label Name="lblTime7" Grid.Column="7" Grid.Row="0" Style="{StaticResource LabelStyle}" Content="-"/>
<Label Name="lblTime8" Grid.Column="8" Grid.Row="0" Style="{StaticResource LabelStyle}" Content="-"/>
<Label Background="Purple" Grid.Column="9" Grid.Row="0"/>
</Grid>
</StackPanel>
</Canvas>
</Viewbox>
</Grid>
Long story short, i'm stuk.... hopefully someone could point me in the right direction.
I have two methods in mind.
First method:
Change to a monospace font, this will ensure that no matter what time value you throw at it, the width will be constant. But you may not find a good/suitable font using this method, though.
Second method:
If you are not using MVVM, try this (C# code, I'm not too used to VB.net):
// Code-behind
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
var label = this.lblTime;
label.Text = "00:00:00";
label.Measure(); // Force it to measure
label.Width = label.DesiredSize.Width;
}
This will force the width to stay constant. Depending on the font, you need to manually set the time value that takes up the most space.
Also, to be sure it works properly, you may need to wrap the Label in a Grid. Make the Grid have 3 columns, set the label in column 1 (middle column), and set the columndefinitions' widths to *, auto and * respectively in that order.
Your Canvas has a width of 300. It looks to me as there is less than 300 px available. This is why the last column is smaller.
#Jai, thanks for pointing me in the direction of the .Measure() Sub. After fiddling around i ended up with the 3 column grid, measuring the size of the label with the new content, setting the size of the label. This causes the Column to realign, which holds the label in place.
The code: (created new WPF program for the test, The colors are to see the difference between child and parent)
<Grid Background="Tomato">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Name="lblTime"
Grid.Column="1"
Grid.Row="0"
Content = "-- : -- : --"
FontSize="50"
Foreground="Black"
Background="Beige"
HorizontalContentAlignment="Left"
VerticalAlignment="Center"
FontFamily="DS-Digital"/>
</Grid>
And the code behind it:
Class MainWindow
''' <summary>
''' Timer for updating the time Clock
''' </summary>
Dim WithEvents tmrSystemTime As New DispatcherTimer With {.Interval = TimeSpan.FromSeconds(1)} 'Set Timer interval on every second.
Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
tmrSystemTime.Start()
End Sub
Private Sub SystemTime_Tick(sender As Object, e As EventArgs) Handles tmrSystemTime.Tick
'Set the time in the label
lblTime.Content = Now.ToString("HH : mm : ss")
'Measure and set the size of the label
MeasureSizeTimeLabel()
End Sub
''' <summary>
''' Measure the Max Size of the label with a specific Format
''' </summary>
Private Sub MeasureSizeTimeLabel()
'Store the Max size of the Time Label in this variable
Dim MaxClockSize As Size
'Measure the Max size of the clock label and use this width
'lblTime.Content = "00 : 00 : 00"
lblTime.Measure(New Size(Double.PositiveInfinity, Double.PositiveInfinity))
MaxClockSize = lblTime.DesiredSize
'Now Set the size of the label
lblTime.Width = MaxClockSize.Width
lblTime.Height = MaxClockSize.Height
End Sub
Thanks all for the help, appreciate the effort and time! :-)
I have an ObservableCollection which contains ViewModel which in turns defines my buttons definitions.
I've been at it for hours, reading articles after articles but to no avail. I've tried using a Listbox and this is the closest I've got to. My buttons are getting build horizontally but assuming I'm displaying 3 buttons, I want one displayed on the left, one displayed in the middle and one displayed on the right.
<ListBox Grid.Row="2" ItemsSource="{Binding Links}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<StackPanel Background="Beige" Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Button Grid.Column="{Binding Column}"
Grid.Row="0"
Width="90"
Height="90">
<ContentControl>
<StackPanel Orientation="Vertical">
<Image Source="{Binding Image}" Width="36" Height="36"
Margin="5" Stretch="UniformToFill"
HorizontalAlignment="Center"/>
<TextBlock Text="{Binding Description}"
Foreground="#0F558E"
FontSize="18"
HorizontalAlignment="Center"/>
</StackPanel>
</ContentControl>
</Button>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
As you can see, I set the column dynamically using a property from my ViewModel but I no longer have a grid as I couldn't get it to work, but ideally I'd like to use a grid so that I can specify in which Column to set the button.
When I use a StackPanel, it works but the buttons are right next to each other rather than being split evenly through the entire width of the screen.
I've done something similar to the above using ItemsControl and using a grid, and I can see each button getting added but they overlap each other in row 0, col 0. If I bind the row to the Column property for testing purposes, it build it correctly but my buttons are displayed on different rows which is not what I want. I want each button to be aligned horizontally.
How can I achieve this? I know I could just hard code 3 buttons and just change their icons and text and handle the relevant code by passing the relevant button as binded parameter, but ideally I'd like to build the buttons dynamically in a grid and position them using the column.
Note that the number of column would be fixed i.e. 3, as I'll never have more than this.
Thanks.
but ideally I'd like to use a grid so that I can specify in which
Column to set the button.
In any Xaml variant, why not just use that Grid, such as shown below, where the Grid is set to consumes all the horizontal space.
Then with the grid's center column to be star sized and to have the rest of the remaining space be consumed after button 1 and button 3, which auto size into their own spaces:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0"/>
<Button Grid.Column="1" HorizontalAlignment="Center"/>
<Button Grid.Column="2"/>
</Grid>
If that fails, set button one's HorizontalAlignment to be Left and button three's as Right.
As an aside with the list box, it may not be stretching to the whole horizontal size of the screen. Check out my answer to a WP8 sizing issue:
ListBoxItem HorizontalContentAlignment.
I eventually found the answer to my problem in an article I found on the web.
You can check it out here: Using Grids with ItemsControl in XAML
In short, you need to subclass the itemsControl and you need overwrite the GetContainerForItemOverride method which will take care of copying the "data" of the ItemTemplate to the ContentPresenter. In this instance, the row and column, but for my requirement, it is just the Column, since my row will always be 0.
Here is core part of the code if you don't want to check the full article which resolve the problem of setting controls horizontally in a grid using ItemsControl but note the article takes care of creating rows & columns dynamically as well, which I'm not interested in for my project.
public class GridAwareItemsControl : ItemsControl
{
protected override DependencyObject GetContainerForItemOverride()
{
ContentPresenter container = (ContentPresenter)base.GetContainerForItemOverride();
if (ItemTemplate == null)
{
return container;
}
FrameworkElement content = (FrameworkElement)ItemTemplate.LoadContent();
BindingExpression rowBinding = content.GetBindingExpression(Grid.RowProperty);
BindingExpression columnBinding = content.GetBindingExpression(Grid.ColumnProperty);
if (rowBinding != null)
{
container.SetBinding(Grid.RowProperty, rowBinding.ParentBinding);
}
if (columnBinding != null)
{
container.SetBinding(Grid.ColumnProperty, columnBinding.ParentBinding);
}
return container;
}
}
The final xaml looks like this:
<controls:GridAwareItemsControl ItemsSource="{Binding Links}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid Background="Pink">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button
Grid.Column="{Binding Column}"
Grid.Row="0"
Width="120" Height="120">
<ContentControl>
<StackPanel Orientation="Vertical">
<Image Source="{Binding Image}" Width="36" Height="36" Margin="5"
Stretch="UniformToFill" HorizontalAlignment="Center"/>
<TextBlock Text="{Binding Description}" Foreground="#0F558E"
FontSize="18" HorizontalAlignment="Center"/>
</StackPanel>
</ContentControl>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</controls:GridAwareItemsControl>
Once I used the new control, my buttons were correctly placed inside the grid, and therefore were evenly spaced out as the grid took care of that wit the ColumnDefinitions.
If anyone knows how to achieve the same without having to create a new control and overriding the method (in other words, pure XAML), please post it as I'd be very interested to see how this can be done.
Thanks and thank you to Robert Garfoot for sharing this great code!
PS: Note that I've simplified my xaml in order to create a test sample without any style on the buttons, so these are rather large if you try based on this sample.
UPDATE:
Small typo correction but my grid column definition was defined as
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
but as #OmegaMan suggested, to be evenly spread, it should have been defined as
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
I was able to accomplish this with a stackpanel inside of a grid, avoiding columns altogether. If you set the stackepanel's HorizontalAlignment to "center", it will center itself inside the grid and grow as buttons are added, still staying centered inside of the grid. Then it's just a matter of margins to have the buttons equally spaced:
<Grid>
<StackPanel
VerticalAlignment="Stretch"
HorizontalAlignment="Center"
Orientation="Horizontal"
>
<Button HorizontalAlignment="Center" Content="Add" Width="104" Height="32" Margin="24,0"/>
<Button HorizontalAlignment="Center" Content="Edit" Width="104" Height="32" Margin="24,0"/>
<Button HorizontalAlignment="Center" Content="Remove" Width="104" Height="32" Margin="24,0"/>
</StackPanel></Grid>
I would like to have something like a resizable Expander. My basic idea was something like this:
<Grid HorizontalAlignment="Left">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="2" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Expander Grid.Column="0" ExpandDirection="Right">
...
</Expander>
<GridSplitter Grid.Column="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
...
</Grid>
The problem with this: if i move the grid splitter and collaps the expander i got a big empty area. How can make the entire column collapse? Or is there another way to make the expander "resizable"
Not sure what you are trying to accomplish but i think conceptually the Grid should be part of the Expander.Content, would this work for you?
<Expander Header="Test" ExpandDirection="Right" HorizontalAlignment="Left" Background="LightBlue">
<Expander.Content>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="5"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Lorem ipsum dolor sit"/>
<GridSplitter Grid.Column="1" Width="5" ResizeBehavior="PreviousAndCurrent" ResizeDirection="Columns"/>
</Grid>
</Expander.Content>
</Expander>
Edit: Removed all the triggering from the first column as it seemed unnecessary.
Also: For this to work vertically the GridSplitter's HorizontalAlignment must be set to Stretch, otherwise it will have zero width by default (of course everything else that is orientation-specific must be adapted as well but that is straightforward)
HorizontalAlignment is the Microsoft .NET property accessor for what is in reality a dependency property. This particular dependency property quite frequently has its apparent "default" value set differently in subclassed elements, particularly controls. [...] For example, the apparent "default" of HorizontalAlignment for a Label control will be Left, even though Label inherits HorizontalAlignment direct from FrameworkElement. This is because that value was reset within the default style of Label, within the style's control template.
Maybe this will help to solve your "column collapse" problem
XAML:
Add in <Grid> Name="expGrid" and add in <Expander> Collapsed="Expander_Collapsed"
C# Code:
private void Expander_Collapsed(object sender, RoutedEventArgs e)
{
var colomnIndex = Grid.GetColumn(sender as Expander);
var colomn = expGrid.ColumnDefinitions[colomnIndex];
colomn.Width = GridLength.Auto;
}
I have two panel , Left Hand site represents the list of options or menu and right hand side will be list of usercontrol assigned to eatch menu items in the left as Listbox or Items control.
The requirement is
eg. If i move the thumb of the scrollbar in the right hand side panel to anyway near the usercontrol2 , the Usercontrol 2 heading in the heading panel should get activated and if iam moving the thumb to the usercontrol1, the usercontrol 1 heading in the heading panel should get activated and so on.
So how to proceed to accomplish these kind of UI.? Any suggestion is greatly appreciated?
The basic idea is to reduce the no of clicks in the Heading Panel. Right hand side is heavily packed with UI elements so user wants to avoid unnecessary click in the heading.
User will not click on the Left side heading panel. While traversing the right hand panel's scrollviewer the heading should automatically get selected to give the user about the control which he is entering or using now.
Following should work:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border Grid.Column="0">
<ItemsControl>
<!--List on Left : List of Usercontrols-->
</ItemsControl>
</Border>
<Border Grid.Column="1">
<ScrollViewer VerticalScrollBarVisibility="Visible"
HorizontalScrollBarVisibility="Disabled">
<ItemsControl>
<!--List on Right : List of Usercontrols-->
</ItemsControl>
</ScrollViewer>
</Border>
</Grid>
Use Template Selectors to select which UserControl to display in lists.
EDIT-
You could try something like following:
XAML:
<Window x:Class="WpfApplication1.Window4"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window4"
Height="300"
Width="300">
<Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<Border Grid.Column="0">
<ListBox Name="ListBox1"
ItemsSource="{Binding}"
HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<Border Height="50"
BorderBrush="Black"
BorderThickness="1"
CornerRadius="5"
Padding="3">
<TextBlock Text="{Binding}" />
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Border>
<Border Grid.Column="1">
<ScrollViewer VerticalScrollBarVisibility="Visible"
HorizontalScrollBarVisibility="Disabled"
ScrollChanged="OnScrollChanged"
Name="ScrollViewer1">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Height="250"
BorderBrush="Black"
BorderThickness="1"
CornerRadius="5"
Padding="3">
<TextBlock Text="{Binding}" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Border>
</Grid>
</Grid>
</Window>
Code:
public partial class Window4 : Window
{
public Window4()
{
InitializeComponent();
DataContext = Enumerable.Range(1, 25);
}
private void OnScrollChanged(object sender, ScrollChangedEventArgs e)
{
var element = ScrollViewer1.InputHitTest(new Point(5, 5));
if (element != null)
{
if (element is FrameworkElement)
{
ListBox1.SelectedItem = (element as FrameworkElement).DataContext;
}
}
}
}
NOTE:
This is just a sample code. Just one of possible ways to do it. And it is not a very healthy piece of code. Some refactoring might be needed. I would wrap this logic up in an Attached Property or a Behavior.
I would use a Scrollbar control and use it somehow like an up/down button. If you move the scroll up you go to the next control and the same moving down.
Not sure if you know what I mean, let me know.