WPF display listview item in a Image control - wpf

I have a Listview and next to it an Image control. I have set CollectionOfCapturedImages for my Listview's ItemsSource.
public ObservableCollection<BitmapImage> CollectionOfCapturedImages { get; } = new ObservableCollection<BitmapImage>();
<ListView x:Name="testListView" ItemsSource="{Binding CollectionOfCapturedImages}" MouseLeftButtonDown="testListView_MouseLeftButtonDown" Height="345" Margin="567,10,10,0" VerticalAlignment="Top">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="1" HorizontalAlignment="Center" VerticalAlignment="Top"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<Image Source="{Binding}" Height="150" Width="150"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
How could I display selected Listview item (BitmapImage) in my Image control?
I have tried to add MouseLeftButtonDown="testListView_MouseLeftButtonDown"
private void testListView_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
newlyAddedImage.Source = testListView.SelectedItem;
}
how can I get this working?

Did you try to just bind the Source property of the Image to the SelectedItem property of the ListView?
<Image x:Name="newlyAddedImage" Source="{Binding SelectedItem, ElementName=testListView}" />

Related

wpf binding issue with ItemsSource

<ItemsControl ItemsSource="{Binding DataViews}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<DataGrid MaxHeight="500" VerticalScrollBarVisibility="Auto" VerticalAlignment="Stretch" Margin="0,0,10,0" MaxColumnWidth="450"
RowStyle="{StaticResource DataGridRowSql}" Style="{StaticResource DataGridStyleSQL}"
ColumnHeaderStyle="{StaticResource StyleDataGridColumnHeaderDefault}" ItemsSource="{Binding}"
IsReadOnly="{Binding RelativeSource={RelativeSource AncestorType=Page},Path=Locked}"
RowEditEnding="DataGrid_RowEditEnding" >
<DataGrid.CommandBindings>
<CommandBinding Command="Copy" Executed="CommandBinding_Executed"></CommandBinding>
</DataGrid.CommandBindings>
<DataGrid.InputBindings>
<KeyBinding Key="C" Modifiers="Ctrl" Command="Copy"></KeyBinding>
</DataGrid.InputBindings>
</DataGrid>
<GridSplitter Background="Red" Height="10" HorizontalAlignment="Stretch" ResizeDirection="Rows" ResizeBehavior="PreviousAndNext"></GridSplitter>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel VerticalAlignment="Stretch"></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
hi, I need to have the updated data in the DataGrid_RowEditEnding event, since the e.Row doesn't have the updated data, so I thought about adding <ItemsControl ItemsSource = "{Binding DataViews, Mode = TwoWay, UpdateSourceTrigger = PropertyChanged}" > but it doesn't work, where am I wrong?
You will get the updated value in the CellEditEnding event handler if you just set the UpdateSourceTrigger property of the bindings to PropertyChanged.
If you are using auto-generated columns, you could handle the AutoGeneratingColumn for the DataGrid to do this:
private void DataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
DataGridBoundColumn dataGridBoundColumn = e.Column as DataGridBoundColumn;
if (dataGridBoundColumn != null)
{
dataGridBoundColumn.Binding = new Binding(e.PropertyName) { UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged };
}
}

XAML nested DataTemplate data-binding

I have an ItemsControl which has its ItemsSource set with a Binding to an ObservableCollection on my ViewModel. I am using a Button control within its ItemTemplate to display my data and I am using a DataTemplate within the Button and none of the Binding data is being displayed. Below is the XAML in question:
<ItemsControl ItemsSource="{Binding Path=ConnectedInstruments}" HorizontalAlignment="Left">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Height="60" VerticalAlignment="Top">
<Button.ContentTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=ModelCode}" />
<TextBlock Text="{Binding Path=SerialNumber}" />
</StackPanel>
</DataTemplate>
</Button.ContentTemplate>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Neither TextBlock controls within the Button DataTemplate are being populated. I understand this has something to do with the Binding path, however I am at a loss as to what I am doing wrong. Can someone put me on the right track please?
EDIT
public class Instrument
{
public string ModelCode { get; set; }
public string SerialNumber { get; set; }
}
public class ViewModel
{
public ObservableCollection<Instrument> ConnectedInstruments { get; set; }
}
I know that the ItemsControl is Binding correctly with the ObservableCollection as the correct count of Button controls are being displayed, only the templated data is missing.
Any specific reason you need to use ContentTemplate instead of directly setting Button's Content like this? :
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Height="60" VerticalAlignment="Top">
<StackPanel>
<TextBlock Text="{Binding Path=ModelCode}" />
<TextBlock Text="{Binding Path=SerialNumber}" />
</StackPanel>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>

ListViewItem Context Menu Get Data from ListViewItem

I'm trying to create a context menu, so that when you right click the ListViewItem, the user is presented with a list of options. The problem is; I can't get the refrenced item linked to the ListViewItem in the Click event.
I think it may be because I'm putting the ContextMenu in the wrong place in my XAML. I have been searching and playing around for ages, but think it could have something to do with the DataTemplate I'm using where the examples weren't in templates.
<ListView Margin="0" Name="FileImagesListView" VerticalAlignment="Top" Grid.Row="0">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<EventSetter Event="Mouse.MouseEnter" Handler="MouseEnterPicFileListItem" />
<EventSetter Event="Mouse.MouseLeave" Handler="MouseLeavePicFileListItem"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Border BorderBrush="{Binding Path=BorderBrushColourID, Converter={StaticResource BorderColourConverter}}" BorderThickness="3" CornerRadius="2">
<StackPanel FlowDirection="LeftToRight" Orientation="Vertical" Margin="3">
<Grid>
<TextBlock TextAlignment="Center" Text="{Binding Path=TimeAgo}" Margin="0,7" ></TextBlock>
<Label Style="{StaticResource CircularLabel}" HorizontalAlignment="Right" Height="35" Margin="0,-8,0,0" Content="{Binding Path=MatchedCount}" Visibility="{Binding Path=MatchedCount, Converter={StaticResource VisibleIfGreaterThanOne}}" ></Label>
</Grid>
<Image Name="FilePic" Height="Auto" Width="160" Source="{Binding Path=BitmapPicture}"></Image>
</StackPanel>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Margin="3" Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
Usually you can get the data item by just calling myListViewItem.DataContext and casting it into whatever it should be.
private void ListViewItem_Click(object sender, EventArgs e)
{
ListViewItem item = sender as ListViewItem;
if (item == null) return;
MyDataItem = item.DataContext as MyDataItem;
// Do whatever here
}
As a side note, WPF ContextMenus do not share the same VisualTree as your application, so trying to bind them to your main UI works differently. Its hard to tell if that is related to your problem because I see no ContextMenu or Click event in your question.
Edit
If your ContextMenu is on a ListBoxItem, then you need to refer to your ContextMenu's PlacementTarget to get the ListBoxItem that the ContextMenu is attached to

Silverlight Data Binding for Collection in Stack Panel

I'm new to Silverlight, so I don't have a complete grasp of all the controls at my disposal. What I would like to do is use databinding and a view model to maintain a collection of items. Here is some mock code for what I'd like to do:
Model
public class MyItem
{
public string DisplayText { get; set; }
public bool Enabled { get; set; }
}
ViewModel
public class MyViewModel : INotifyPropertyChanged
{
private ObservableCollection<MyItem> _myItems = new ObservableCollection<MyItem>();
public ObservableCollection<MyItem> MyItems
{
get { return _myItems; }
set
{
_myItems = value
NotifyPropertyChanged(this, "MyItems");
}
}
}
View
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel ItemsSource="{Binding MyItems}">
<StackPanel Orientation="Horizontal">
<CheckBox "{Binding Enabled, Mode=TwoWay}"></CheckBox>
<TextBlock Text="{Binding DisplayText, Mode=TwoWay}" />
</StackPanel>
</StackPanel>
</Grid>
So my end goal would be that every time I add another MyItem to the MyItems collection it would create a new StackPanel with checkbox and textblock. I don't have to use a stack panel but just thought I'd use that for this sample.
Looks like you want a <ListBox>, then set the <ListBox.ItemTemplate> to your <StackPanel> something like this.....
<ListBox ItemsSource=”{Binding Classes, Source={StaticResource model}}”>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox "{Binding Enabled, Mode=TwoWay}"/>
<TextBlock Text="{Binding DisplayText, Mode=TwoWay}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
here is a great example (it's WPF, but should only be minor changes for silverlight)
yes, looks like you want a <ListBox>
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SilverlightApplication4.MainPage"
Width="640" Height="480">
<UserControl.Resources>
<DataTemplate x:Key="ItemTemplate">
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding Enabled, Mode=TwoWay}"/>
<TextBlock Text="{Binding DisplayText}"/>
</StackPanel>
</DataTemplate>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White" DataContext="{Binding Source={StaticResource SampleDataSource}}">
<ListBox Margin="0,0,8,0" ItemTemplate="{StaticResource ItemTemplate}" ItemsSource="{Binding Collection}"/>
</Grid>
This code will give you a ListBox with all your Data bound to a Checkbox and TextBlock with the Checkbox first and TextBox next to it.

In a horizontal listbox how do I align items to the top?

In a horizontal listbox how do I align items to the top?
I have ran out of ideas of where to stick a VerticalAlignment="Top".
<Window.Resources>
<DataTemplate DataType="{x:Type l:MyType}">
<Grid VerticalAlignment="Top">
<TextBlock VerticalAlignment="Top" Text="{Binding MyValue}" Background="Yellow"/>
</Grid>
</DataTemplate>
</Window.Resources>
<Grid>
<ListBox Name="listBox" ItemsSource="{Binding}" VerticalAlignment="Top" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" VerticalAlignment="Top"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<ListBoxItem Content="{Binding}" VerticalAlignment="Top" VerticalContentAlignment="Top"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
using System.Windows;
namespace WpfApplication5 {
public partial class Window1 :Window {
public Window1() {
InitializeComponent();
this.listBox.ItemsSource = new MyType[] {
new MyType{ MyValue = "Tall\nItem" },
new MyType{ MyValue = "I want this aligned to the top" } };
}
}
public class MyType {
public string MyValue { get; set; }
}
}
You need to set the VerticalContentAlignment on the list box, all the other alignments you have in there can be removed as well once that is set.
....
<ListBox Name="listBox" ItemsSource="{Binding}" VerticalContentAlignment="Top" >
....
The default for the VerticalContentAlightment on your ListBox is 'Center', so even though you were setting the VerticalAlignment elsewhere it was just aligning to the top of the ListBoxItems, which were still centered instead of streched or placed at the top. If you set the VerticalContentAlignment to Stretch then you'd see the other VerticalAlignment="Top" declarations work.

Resources