I'm trying to get an item in ListView in WPF when user doesn't select an item by clicking on it but the user taps on it.
Is there a way to achieve this in WPF ListView.
ListView dataSource is filled by a dynamic collection in code-behind.
I'm getting a null object when user taps on it.
Item selectedItem = (Item)lv_CartItems.SelectedItem;
this is how my data-template looks like for listview.
<ListView.ItemTemplate>
<DataTemplate>
<Viewbox>
<Grid Width="230" Height="110" >
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width=".1*" />
<ColumnDefinition />
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition Width=".5*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="2*" />
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border BorderBrush="LightGray" BorderThickness="1"
Grid.Row="0" Grid.Column="0"
Grid.ColumnSpan="6" Grid.RowSpan="3" >
</Border>
<Viewbox Grid.Row="0" >
<Image Name="img_ItemImage"
Source="{Binding Image, Mode=TwoWay }"
Width="20" Height=" 25" />
</Viewbox>
<Viewbox Grid.Column="2" Grid.ColumnSpan="3" VerticalAlignment="Top" >
<TextBlock Name="lbl_ItemName" TextWrapping="Wrap" Width="180" Foreground="Gray"
Text="{Binding Name , Mode=TwoWay }" Tag="{Binding SKU_No,Mode=TwoWay}" >
</TextBlock>
</Viewbox>
<Viewbox Grid.Row="1" Margin="10,0" VerticalAlignment="Top" >
<TextBlock Foreground="Gray" >Qty:</TextBlock>
</Viewbox>
<Viewbox Grid.Row="2" Margin="0,0" VerticalAlignment="Top" >
<StackPanel Orientation="Horizontal" >
<Button Name="btn_Minus" FontWeight="ExtraBold" Padding="0" Width="12"
Resources="{StaticResource cartitembutton}" Click="btn_Minus_Click" >
<Image Source="/Resources\Icons\minus.png" ></Image>
</Button>
<Border BorderThickness="1" Margin="2,0" Width="13" CornerRadius="2" BorderBrush="LightGray" >
<TextBlock Name="lbl_Quantity" FontWeight="Bold" Foreground="Gray"
HorizontalAlignment="Center" VerticalAlignment="Center"
Text="{Binding Quantity , Mode=TwoWay }">
</TextBlock>
</Border>
<Button Name="btn_Increment" FontWeight="ExtraBold" Width="12"
Resources="{StaticResource cartitembutton}"
Padding="0"
Click="btn_Increment_Click">
<Image Source="/Resources\Icons\union_10.png" ></Image>
</Button>
</StackPanel>
</Viewbox>
<Viewbox Grid.Row="1" Grid.Column="2" Margin="5,0"
HorizontalAlignment="Left" Grid.ColumnSpan="3" >
<TextBlock Name="lbl_Price" FontWeight="DemiBold"
Text="{Binding Price , Mode=TwoWay}" ></TextBlock>
</Viewbox>
<Viewbox Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="3"
VerticalAlignment="Top" Margin="0,0" >
<TextBlock Name="lbl_Appearence"
Text="{Binding Appearance , Mode=TwoWay }"
TextWrapping="Wrap" Foreground="Gray" Width="210" >
</TextBlock>
</Viewbox>
<Viewbox Grid.Column="5" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="2,2"
>
<Button Name="btn_DeleteItem"
Click="btn_DeleteItem_Click"
Resources="{StaticResource cartitembutton}" >
<Image Source="/Resources/Icons/delete.png" ></Image>
</Button>
</Viewbox>
</Grid>
</Viewbox>
</DataTemplate>
</ListView.ItemTemplate>
You should use data binding to retrieve the selected item. The source property will be automatically updated when the ListView.SelectedItem changes.
Touch is handled the same way as click is handled. The framework converts touch events to mouse events.
I noticed that you wrapped every element into a ViewBox. That is not necessary and will only degrade performance. When the elements are hosted inside a Grid they will resize automatically by default. Exceptions are elements that need an initial size like Shape or Image. But since the item containers won't resize themselves, the content of the containers won't resize too.
To force all elements to occupy max horizontal space you can set a Style that targets the item container:
<ListView.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment"
Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register(
"Items",
typeof(ObservableCollection<Item>),
typeof(MainWindow),
new PropertyMetadata(default(ObservableCollection<Item>)));
public ObservableCollection<Item> Items
{
get => (ObservableCollection<Item>) GetValue(MainWindow.ItemsProperty);
set => SetValue(MainWindow.ItemsProperty, value);
}
public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register(
"SelectedItem",
typeof(Item),
typeof(MainWindow),
new PropertyMetadata(default(Item), MainWindow.OnSelectedItemChanged));
public Item SelectedItem
{
get => (Item) GetValue(MainWindow.SelectedItemProperty);
set => SetValue(MainWindow.SelectedItemProperty, value);
}
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
this.Items = new ObservableCollection<Item>();
// Initialize data source
CreateItems();
}
// Property changed callback of the SelectedItem property
private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
// Reference to instance members in a class scope
var _this = d as MainWindow;
if (e.NewValue is ItemCollection selectedItem)
{
// Handle currently selected item
}
}
}
MainWindow.xaml
<Window>
<ListView ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem}" />
</Window>
Related
I'm working on a UWP FTP front-end application. I've created a UserControl that mimics the form of a standard Windows desktop icon (consisting of a StackPanel containing an Image and a TextBlock) which is to be used as a way of displaying saved favorites. What I'd like is for the user to be able to select any image to be used as the icon for each favorite, but have run into some pretty significant issue with getting this to work, I believe due to the Windows 10 "no access to filesystem" restriction--I haven't figured out that part yet.
As a temporary substitution, I came up with the idea of having a set of icons for the user to select from, all stored within the Assets folder of the application. I've created an IconSelector page/child window (IconSelector.xaml) that pops up when appropriate, allowing the user to select from 8 different Images.
The issue I'm running into is getting the selected Image back to the parent window (MainPage.xaml). I thought of just passing an int from child to parent, and then use that int with an enum to indicate the correct image, but I can't figure out how to pass any parameter at all between child and parent.
I did find this question on SO, but it's for Silverlighbt and doesn't seem to work in UWP (unless I implemented it incorrectly).
Does anybody have any idea on how to accomplish this? Code (relevant portions) pasted below:
MainPage XAML
<Canvas Grid.Column="1" Grid.Row="0" Grid.RowSpan="5" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Image Source="Assets\Red.png" Canvas.ZIndex="200" />
<Border x:Name="addFtpGrid" Visibility="Visible" Canvas.Left="300" Canvas.Top="300" Width="600" Height="350" BorderBrush="{ThemeResource SystemControlBackgroundAccentRevealBorderBrush}" BorderThickness="3">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1.5*" />
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="1.5*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="Link name" Grid.Column="0" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5,0" />
<TextBlock Text="Address" Grid.Column="0" Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5,0" />
<TextBlock Text="Username" Grid.Column="0" Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5,0" />
<TextBlock Text="Password" Grid.Column="0" Grid.Row="3" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5,0" />
<TextBlock Text="Confirm Password" Grid.Column="0" Grid.Row="4" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="5,0" />
<TextBox x:Name="linkNameEntry" HorizontalAlignment="Stretch" VerticalAlignment="Center" Grid.Column="1" Grid.Row="0" Margin="5,0" />
<TextBox x:Name="addressEntry" Text="ftp://" HorizontalAlignment="Stretch" VerticalAlignment="Center" Grid.Column="1" Grid.Row="1" Margin="5,0" />
<TextBox x:Name="usernameEntry" HorizontalAlignment="Stretch" VerticalAlignment="Center" Grid.Column="1" Grid.Row="2" Margin="5,0" />
<PasswordBox x:Name="passwordEntry" HorizontalAlignment="Stretch" VerticalAlignment="Center" Grid.Column="1" Grid.Row="3" Margin="5,0">
</PasswordBox>
<PasswordBox x:Name="confirmPasswordEntry" HorizontalAlignment="Stretch" VerticalAlignment="Center" Grid.Column="1" Grid.Row="4" Margin="5,0" LostFocus="ConfirmPasswordEntry_LostFocus" />
<Viewbox Grid.Column="2" Grid.Row="0" Grid.RowSpan="4" Margin="5,15,5,0">
<Image x:Name="imageEntry" Source="Assets/SquircleX.png" Tapped="ImageEntry_TappedAsync" />
</Viewbox>
<TextBlock Text="Click image to change" Grid.Column="2" Grid.Row="4" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Button x:Name="saveNewFtpLink" Click="SaveNewFtpLink_Click" Content="Save Changes" Grid.Column="0" Grid.Row="5" Grid.ColumnSpan="3" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,10"/>
</Grid>
</Border>
</Canvas>
MainPage C#
private async void ImageEntry_TappedAsync(object sender, TappedRoutedEventArgs e)
{
IconSelector selector = new IconSelector();
selector.Tapped += new TappedEventHandler(selector_Tapped);
ShowDialog(selector);
//List<string> fileTypes = new List<string> { ".jpg", ".jpeg", ".png", ".bmp", ".gif", ".tiff", ".ico" };
//FileOpenPicker picker = new FileOpenPicker();
//picker.ViewMode = PickerViewMode.Thumbnail;
//picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
//foreach (string type in fileTypes)
//{
// picker.FileTypeFilter.Add(type);
//}
//StorageFile file = await picker.PickSingleFileAsync();
//if(file != null)
//{
// imageEntry.Source = new BitmapImage(new Uri(file.Path));
// Image selectedImage = new Image();
// selectedImage.Source = imageEntry.Source;
// imageEntry = selectedImage;
// imageEntry.UpdateLayout();
// imageToken = StorageApplicationPermissions.FutureAccessList.Add(file);
//}
}
IconSelector XAML
<Page
x:Class="FtpSharp.IconSelector"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:FtpSharp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignHeight="175" d:DesignWidth="600"
Background="{ThemeResource ContentDialogBackgroundThemeBrush}">
<Page.Resources>
<Style x:Key="selectionStyle" TargetType="Border">
<Setter Property="CornerRadius" Value="10" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Margin" Value="10,10,5,5" />
<Setter Property="BorderThickness" Value="3" />
</Style>
</Page.Resources>
<Grid VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ScrollViewer HorizontalScrollBarVisibility="Auto">
<StackPanel x:Name="iconViewer" Orientation="Horizontal" Width="1100">
<Border Style="{StaticResource selectionStyle}">
<Image Source="Assets\FtpRed.png" Margin="4" Height="96" Tapped="Image_Tapped" />
</Border>
<Border Style="{StaticResource selectionStyle}">
<Image Source="Assets\FtpOrange.png" Margin="4" Height="96" Tapped="Image_Tapped" />
</Border>
<Border Style="{StaticResource selectionStyle}">
<Image Source="Assets\FtpYellow.png" Margin="4" Height="96" Tapped="Image_Tapped" />
</Border>
<Border Style="{StaticResource selectionStyle}">
<Image Source="Assets\FtpGreen.png" Margin="4" Height="96" Tapped="Image_Tapped" />
</Border>
<Border Style="{StaticResource selectionStyle}">
<Image Source="Assets\FtpBlue.png" Margin="4" Height="96" Tapped="Image_Tapped" />
</Border>
<Border Style="{StaticResource selectionStyle}">
<Image Source="Assets\FtpPurple.png" Margin="4" Height="96" Tapped="Image_Tapped" />
</Border>
<Border Style="{StaticResource selectionStyle}">
<Image Source="Assets\FtpPink.png" Margin="4" Height="96" Tapped="Image_Tapped" />
</Border>
<Border Style="{StaticResource selectionStyle}">
<Image Source="Assets\FtpTeal.png" Margin="4" Height="96" Tapped="Image_Tapped" />
</Border>
</StackPanel>
</ScrollViewer>
<Button x:Name="commitSelection" Content="Save" Grid.Row="1" Foreground="Black" HorizontalAlignment="Center" Margin="0,10" />
</Grid>
IconSelector C#
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
namespace FtpSharp
{
public sealed partial class IconSelector : Page
{
private static readonly DependencyProperty SelectedIconProperty = DependencyProperty.Register("SelectedIcon", typeof(int),
typeof(IconSelector), new PropertyMetadata(0));
public int SelectedIcon
{
get { return (int)GetValue(SelectedIconProperty); }
set { SetValue(SelectedIconProperty, value); }
}
public IconSelector()
{
this.InitializeComponent();
}
private void Image_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
{
Image tappedImage = (Image)sender;
Border tappedBorder = (Border)tappedImage.Parent;
SolidColorBrush blue = new SolidColorBrush(Colors.Blue);
foreach (Border border in iconViewer.Children)
{
border.BorderBrush = new SolidColorBrush(Colors.Transparent);
}
tappedBorder.BorderBrush = new SolidColorBrush(Color.FromArgb(255,0,0,255));
}
}
In this case you can either provide the result as a public property of the IconSelector class, or as EventArgs of an event. You already have the SelectedIcon property there, so you can use it. To notify the MainPage that the selection has occurred, you need to add an event to IconSelector - for example DialogCompleted:
public event EventHandler<int> DialogCompleted;
You will trigger this event when the dialog is confirmed by the user:
DialogCompleted?.Invoke(this, SelectedIcon);
Then within MainPage, you need to subscribe to this event:
IconSelector selector = new IconSelector();
selector.DialogCompleted += IconDialogCompleted;
ShowDialog(selector);
And now get the SelectedIcon inside the handler:
private void IconDialogCompleted(object sender, int selectedIcon)
{
//do something with selectedIcon
}
I have an ItemsControl with DataTemplate in my Page.Xaml and the code is like below:
<ItemsControl x:Name="chatUI" VerticalAlignment="Bottom">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid x:Name="myGrid" Width="340" Background="{Binding Background}" HorizontalAlignment="{Binding GridHorizontalAlign}" Margin="10,0,10,10" MinHeight="45" BorderBrush="#FF003A4F" BorderThickness="0,0,0,2">
<Polygon Visibility="{Binding RightVisibility}" Fill="{Binding Background}" Points="0,0 5,6, 0,12" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="0,0,-5,0" />
<Polygon Visibility="{Binding LeftVisibility}" Fill="{Binding Background}" Points="5,0 0,6, 5,12" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="-5,0,0,0" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="{Binding Text}" TextWrapping="Wrap" FontSize="15" FontFamily="Segoe UI" Foreground="White" Margin="10,10,10,0"/>
<TextBlock Grid.Row="1" Text="{Binding Time}" TextWrapping="Wrap" FontSize="11" FontFamily="Segoe UI" Foreground="LightGray" Margin="10,0,10,5" VerticalAlignment="Bottom" TextAlignment="Right"/>
</Grid>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
What I need right now is getting Text which is bound to the TextBlock when I right click on the grid named myGrid. How is that possible in C#?
We can add the RightTapped event of the Grid, it will be fired when you right click the Grid.
In the RightTapped event we can use Grid.Children to get the collection of child elements of the Grid. That we can get the Grid in the root Grid that named myGrid. That we can use the Grid.Children to get the TextBlock in the Grid.
For example:
private async void myGrid_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
var RightTapGrid = sender as Grid;
var childernElements = RightTapGrid.Children;
foreach (var item in childernElements)
{
var grid = item as Grid;
if (grid != null)
{
var itemchildernElements = grid.Children;
foreach (var text in itemchildernElements)
{
var textBlock = text as TextBlock;
var dialog = new ContentDialog()
{
Title = textBlock.Text,
MaxWidth = this.ActualWidth
};
dialog.PrimaryButtonText = "OK";
dialog.SecondaryButtonText = "Cancel";
await dialog.ShowAsync();
break;
}
}
}
}
If you get your Binding Data from Class called ClassName
You can try this code
XAML:
<ListView x:Name="chatUI" VerticalAlignment="Bottom" SelectionChanged="chatUI_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate>
<Grid x:Name="myGrid" Width="340" Background="{Binding Background}" HorizontalAlignment="{Binding GridHorizontalAlign}" Margin="10,0,10,10" MinHeight="45" BorderBrush="#FF003A4F" BorderThickness="0,0,0,2">
<Polygon Visibility="{Binding RightVisibility}" Fill="{Binding Background}" Points="0,0 5,6, 0,12" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="0,0,-5,0" />
<Polygon Visibility="{Binding LeftVisibility}" Fill="{Binding Background}" Points="5,0 0,6, 5,12" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="-5,0,0,0" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="{Binding Text}" TextWrapping="Wrap" FontSize="15" FontFamily="Segoe UI" Foreground="White" Margin="10,10,10,0"/>
<TextBlock Grid.Row="1" Text="{Binding Time}" TextWrapping="Wrap" FontSize="11" FontFamily="Segoe UI" Foreground="LightGray" Margin="10,0,10,5" VerticalAlignment="Bottom" TextAlignment="Right"/>
</Grid>
</Grid>
</DataTemplate>
</Listview.ItemTemplate>
And add SelectionChanged Event :
private void chatUI_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListView view = (ListView)sender;
//Get Selected Item
ClassName class = view.SelectedItem as ClassName;
string path = class.Text;
// Now we have Text of selected item in Listview
}
I'm working on a WIN 8.1 App. In my App I have a ListView where I'm binding a observable collection from a ViewModel. So far everything works fine. The Problem is, that in the Background all the Data will be loaded correctly, but my ListView displays after approximately 40 elements, from the beginning... In the Background the right Object is selected and 80 Objects are loaded.
Could it be a Problem with the Scrolling?
Does anyone know, how to solve this issue?
From an other Page, i navigate to the Page with the ListView:
private void ShowReturnData()
{
ReturnViewModel retVM = new ReturnViewModel(_navigationService, SelectedTour);
_navigationService.NavigateTo(ViewModelLocator.ReturnPageKey, retVM);
}
In my ViewModel Constructor, I add my data to the observable Collection:
I'm working with MVVMlight.
Properties (ObservableCollection, SelectedItem):
--> observable Collection
/// <summary>
/// The <see cref="Data" /> property's name.
/// </summary>
public const string DataPropertyName = "Data";
private ObservableCollection<ReturnData> _myProperty = new ObservableCollection<ReturnData>();
/// <summary>
/// Sets and gets the Data property.
/// Changes to that property's value raise the PropertyChanged event.
/// </summary>
public ObservableCollection<ReturnData> Data
{
get
{
return _myProperty;
}
set
{
if (_myProperty == value)
{
return;
}
_myProperty = value;
RaisePropertyChanged(DataPropertyName);
}
}
--> SelectedItem
/// <summary>
/// The <see cref="SelectedItem" /> property's name.
/// </summary>
public const string SelectedItemPropertyName = "SelectedItem";
private ReturnData _selectedItem = null;
/// <summary>
/// Sets and gets the SelectedTour property.
/// Changes to that property's value raise the PropertyChanged event.
/// </summary>
public ReturnData SelectedItem
{
get
{
return _selectedItem;
}
set
{
if (_selectedItem == value)
{
return;
}
if (_selectedItem != null)
{
_selectedItem.IsFirstItem = false;
_selectedItem.IsLastItem = false;
}
_selectedItem = value;
if (_selectedItem != null)
{
setIsFirstOrLastItem(Data.IndexOf(_selectedItem));
}
RaisePropertyChanged(SelectedItemPropertyName);
}
}
ViewModel Constructor:
public ReturnViewModel(INavigationService navigationService, TourDetailData tourDetails)
{
//Services
_navigationService = navigationService;
//Commands
PrevPageCommand = new RelayCommand(GoToPrevPage);
TourDetails = tourDetails;
TourCustomerName = "Tour " + tourDetails.Tour + " > " + tourDetails.AccountName;
Data = new ObservableCollection<ReturnData>(from i in TourDetails.ReturnData orderby Convert.ToInt32(i.ItemId) select i);
}
XAML:
<ListView x:Name="lvItems"
Grid.Row="2"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
ItemTemplate="{StaticResource ReturnDataTemplate}"
ItemContainerStyle="{StaticResource ReturnDataListViewItemStyle}"
ItemsSource="{Binding Data}"
Margin="0,5,0,0"
Loaded="lvItems_Loaded">
</ListView>
DataTemplate:
<DataTemplate x:Key="ReturnDataTemplate">
<Grid x:Name="grid" d:DesignWidth="1344.53" d:DesignHeight="123.228">
<Grid.Resources>
<converter:SelectionConverter x:Key="SelectionConverter" Context="{Binding}" />
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="450*"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<Rectangle Grid.Row="0" Grid.ColumnSpan="5" Height="100" Fill="LightGray" Visibility="Collapsed"/>
<Rectangle Grid.Row="2" Grid.ColumnSpan="5" Height="100" Fill="LightGray" Visibility="Collapsed"/>
<!--<Rectangle Grid.Row="0" Grid.ColumnSpan="5" Height="100" Fill="LightGray" Visibility="{Binding IsFirstItem, Converter={StaticResource BoolToVisibilityConverter}}"/>
<Rectangle Grid.Row="2" Grid.ColumnSpan="5" Height="100" Fill="LightGray" Visibility="{Binding IsLastItem, Converter={StaticResource BoolToVisibilityConverter}}"/>-->
<Rectangle Grid.Row="1" Fill="{StaticResource OrangeHighlight}" Visibility="{Binding IsDirty, Converter={StaticResource BoolToVisibilityConverter}}"/>
<StackPanel Grid.Row="1" Grid.Column="1" VerticalAlignment="Center" Margin="15,0">
<TextBlock TextWrapping="Wrap" FontSize="42.667" FontFamily="Segoe UI" Text="{Binding ItemId}" FontWeight="SemiBold"/>
<TextBlock TextWrapping="Wrap" Text="{Binding ItemName}" FontSize="32" FontFamily="Segoe UI"/>
</StackPanel>
<!--<TextBox x:Name="tbxReturn" Grid.Row="1" TextWrapping="Wrap" Grid.Column="2" FontFamily="Segoe UI" FontSize="42.667" Text="{Binding Return}" HorizontalAlignment="Center" VerticalAlignment="Center" Style="{StaticResource TextBoxStyleValues}" PreventKeyboardDisplayOnProgrammaticFocus="True" DoubleTapped="tbxReturn_DoubleTapped" GotFocus="tbxReturn_GotFocus" />-->
<TextBox x:Name="tbxReturn" Grid.Row="1" TextWrapping="Wrap" Grid.Column="2" FontFamily="Segoe UI" FontSize="42.667" Text="{Binding Return}" HorizontalAlignment="Center" VerticalAlignment="Center" Style="{StaticResource TextBoxStyleValues}" DoubleTapped="tbxReturn_DoubleTapped" GotFocus="tbxReturn_GotFocus" InputScope="CurrencyAmountAndSymbol" Foreground="#FF520164" />
<TextBox x:Name="tbxMold" Grid.Row="1" TextWrapping="Wrap" Text="{Binding Mildew}" Grid.Column="3" FontFamily="Segoe UI" FontSize="42.667" HorizontalAlignment="Center" VerticalAlignment="Center" Style="{StaticResource TextBoxStyleValues}" DoubleTapped="tbxMold_DoubleTapped" Tapped="tbxMold_Tapped" GotFocus="tbxMold_GotFocus" InputScope="CurrencyAmountAndSymbol" Foreground="#FF019E90" />
<TextBox x:Name="tbxCredit" Grid.Row="1" TextWrapping="Wrap" Text="{Binding Credit}" Grid.Column="4" FontFamily="Segoe UI" FontSize="42.667" HorizontalAlignment="Center" VerticalAlignment="Center" Style="{StaticResource TextBoxStyleValues}" DoubleTapped="tbxCredit_DoubleTapped" Tapped="tbxCredit_Tapped" GotFocus="tbxCredit_GotFocus" InputScope="CurrencyAmountAndSymbol" Foreground="#FF005C9C" />
<!--<Button Grid.Row="1" Content="+" HorizontalAlignment="Stretch" VerticalAlignment="Top" Grid.Column="2" Height="100" Margin="0,-100,0,0" FontSize="48" Style="{StaticResource NumUpDownButtonStyle}" Visibility="{Binding ElementName=lvItems, Path=DataContext.SelectedItem, ConverterParameter=Selected, Converter={StaticResource SelectionConverter}}" Command="{Binding DataContext.IncreaseReturnCommand, ElementName=lvItems}" Opacity="0.9"/>
<Button Grid.Row="1" Content="-" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Grid.Column="2" Margin="0,0,0,-100" Height="100" FontSize="48" Style="{StaticResource NumUpDownButtonStyle}" Visibility="{Binding ElementName=lvItems, Path=DataContext.SelectedItem, ConverterParameter=Selected, Converter={StaticResource SelectionConverter}}" Command="{Binding DataContext.DecreaseReturnCommand, ElementName=lvItems}" Opacity="0.9"/>
<Button Grid.Row="1" Content="+" HorizontalAlignment="Stretch" VerticalAlignment="Top" Grid.Column="3" Height="100" Margin="0,-100,0,0" FontSize="48" Style="{StaticResource NumUpDownButtonStyle}" Visibility="{Binding ElementName=lvItems, Path=DataContext.SelectedItem, ConverterParameter=Selected, Converter={StaticResource SelectionConverter}}" Command="{Binding DataContext.IncreaseMildewCommand, ElementName=lvItems}" Opacity="0.9"/>
<Button Grid.Row="1" Content="-" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Grid.Column="3" Margin="0,0,0,-100" Height="100" FontSize="48" Style="{StaticResource NumUpDownButtonStyle}" Visibility="{Binding ElementName=lvItems, Path=DataContext.SelectedItem, ConverterParameter=Selected, Converter={StaticResource SelectionConverter}}" Command="{Binding DataContext.DecreaseMildewCommand, ElementName=lvItems}" Opacity="0.9"/>
<Button Grid.Row="1" Content="+" HorizontalAlignment="Stretch" VerticalAlignment="Top" Grid.Column="4" Height="100" Margin="0,-100,0,0" FontSize="48" Style="{StaticResource NumUpDownButtonStyle}" Visibility="{Binding ElementName=lvItems, Path=DataContext.SelectedItem, ConverterParameter=Selected, Converter={StaticResource SelectionConverter}}" Command="{Binding DataContext.IncreaseCreditCommand, ElementName=lvItems}" Opacity="0.9"/>
<Button Grid.Row="1" Content="-" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Grid.Column="4" Margin="0,0,0,-100" Height="100" FontSize="48" Style="{StaticResource NumUpDownButtonStyle}" Visibility="{Binding ElementName=lvItems, Path=DataContext.SelectedItem, ConverterParameter=Selected, Converter={StaticResource SelectionConverter}}" Command="{Binding DataContext.DecreaseCreditCommand, ElementName=lvItems}" Opacity="0.9"/>-->
</Grid>
</DataTemplate>
Style:
<Style x:Key="ReturnDataListViewItemStyle" TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<ListViewItemPresenter x:Name="listViewItemPresenter" d:DesignWidth="938.908" d:DesignHeight="103.083"
ContentMargin="0"
DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}"
DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}"
HorizontalContentAlignment="Stretch"
Padding="0"
PointerOverBackgroundMargin="1"
ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}"
SelectionCheckMarkVisualEnabled="False"
SelectedBorderThickness="0"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
Margin="15,0,0,0"
SelectedForeground="Black"
SelectedPointerOverBackground="{StaticResource OrangeBackground}"
SelectedPointerOverBorderBrush="{StaticResource OrangeBackground}"
SelectedBackground="{StaticResource OrangeBackground}"
DataContext="{Binding SelectedItem}"
Content="{Binding Mode=OneWay}"
ContentTransitions="{TemplateBinding ContentTransitions}"
PlaceholderBackground="{StaticResource BackgroundGray}">
</ListViewItemPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>
<!--<Setter Property="ContentTemplate" Value="{StaticResource ReturnDataTemplate}"/>-->
</Style>
In the Code behind of the XAML Page, I added the behavior of the ScrollViewer:
private void lvItems_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
SetScrollViewer();
}
private async void SetScrollViewer()
{
if (lvItems.SelectedItem == null)
return;
var item = lvItems.SelectedItem;
var listViewItem = (FrameworkElement)lvItems.ContainerFromItem(item);
if (listViewItem == null)
{
lvItems.ScrollIntoView(item);
}
while (listViewItem == null)
{
await Task.Delay(1);
listViewItem = (FrameworkElement)lvItems.ContainerFromItem(item);
}
var topLeft =
listViewItem
.TransformToVisual(lvItems)
.TransformPoint(new Point()).Y;
var lvih = listViewItem.ActualHeight;
var lvh = lvItems.ActualHeight;
var desiredTopLeft = (lvh - lvih) / 2.0;
var desiredDelta = topLeft - desiredTopLeft;
// Calculations relative to the ScrollViewer within the ListView
var scrollViewer = lvItems.GetFirstDescendantOfType<ScrollViewer>();
var currentOffset = scrollViewer.VerticalOffset;
var desiredOffset = currentOffset + desiredDelta;
//scrollViewer.ScrollToVerticalOffset(desiredOffset);
// better yet if building for Windows 8.1 to make the scrolling smoother use:
scrollViewer.ChangeView(null, desiredOffset, null);
}
How i can bind observable collection Count value in textblock in windows phone in listbox
<Grid Margin="440,26,10,0" Grid.Row="1" HorizontalAlignment="Right">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,0,0,0">
<Grid Height="25" MinWidth="25">
<Grid.Background>
<ImageBrush ImageSource="{Binding Image}" Stretch="Fill"/>
</Grid.Background>
<TextBlock Name="Message_Count" Text="{Binding CollectionCount}" Foreground="White" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</StackPanel>
</Grid>
List<CountMsg> retrieved = dbConnCount.Table<CountMsg>().ToList<CountMsg>();
dbCount = new ObservableCollection<CountMsg>(retrieved);
i want to bind dbCount.Count in textblock;
Here is an example:
MainWindow.cs:
ObservableCollection<CountMsg> dbCount;
public int CollectionCount
{
get
{
return dbCount.Count;
}
}
public MainWindow()
{
InitializeComponent();
DataContext = this;
List<CountMsg> retrieved = dbConnCount.Table<CountMsg>().ToList<CountMsg>();
dbCount = new ObservableCollection<CountMsg>(retrieved);
}
Xaml:
<Window x:Class="MainWindow">
....
<TextBlock Text="{Binding CollectionCount}" ... />
....
</Window>
In my Windows Phone application I have a listBox with ContentItems binding :
private ObservableCollection<ContentItemViewModel> _contentItems;
public ObservableCollection<ContentItemViewModel> ContentItems
{
get { return _contentItems; }
}
<ListBox x:Name="ContentListBox" Margin="0,117,12,0" VirtualizingStackPanel.VirtualizationMode="Standard" Logic1:TiltEffect.IsTiltEnabled="True" ItemsSource="{Binding ContentItems}" Tap="ContentListBox_Tap" MinHeight="656" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="vertical" >
<Grid Height="{Binding ItemHeight}" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" x:Name="itemIco1" Width="Auto" Height="Auto" HorizontalAlignment="Left" Source="{Binding IconURL}" Stretch="Fill" CacheMode="BitmapCache" VerticalAlignment="Top" Margin="5,5,5,5" Visibility="Visible"/>
<ListBox IsHitTestVisible="False" Grid.Column="1" VerticalAlignment="Center" >
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
<TextBlock x:Name="ContentCategoryTitle" Height="70" Text="{Binding ContentTitle}" Width="460" Margin="5,34,0,0" TextTrimming="WordEllipsis" TextWrapping="NoWrap" FontSize="28" FontFamily="Segoe WP Semibold" Foreground="#FFF7F7F7" VerticalAlignment="Bottom" />
</ListBox>
</Grid>
<Rectangle Fill="#FF585858" Height="1" Margin="0,0,0,0" Width="460" VerticalAlignment="Bottom" HorizontalAlignment="Left" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Is it possible to binding not an ObservableCollection<ContentItemViewModel>, but - ObservableCollection<List<ContentItemViewModel>> ?
Yes that is possible, if you have a collection of collections. Or why not this?
ObservableCollection<ObservableCollection<ContentItemViewModel>>
If you want your UI to be notified of collection changes to your sub collections.
Update
For example:
View Model
public ObservableCollection<ObservableCollection<ContentItemViewModel>> ContentItems
{
get { return _contentItems; }
set { _contentItems = value; // Notify of property change here, this allows you to change the ContentItems reference after view model construction }
}
public MyViewModel()
{
// Populate content items
this.ContentItems = new ObservableCollection
{
new ObservableCollection { new ContentItemViewModel() },
new ObservableCollection { new ContentItemViewModel(), new ContentItemViewModel() }
};
}
View
<ListBox ItemsSource="{Binding ContentItems}" ...>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<ListBox ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding MyContentItemViewModelProperty}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</DataTemplate>
<ListBox.ItemTemplate>
</ListBox>