It is necessary to arrange elements in certain cells, but they all fall into the upper-left cell. Thought does not work due to the dynamic creation of rows and columns, but in static ad, nothing has changed.
Please help.
XAML
<ItemsControl x:Name="ItControl" ItemTemplate="{StaticResource DefaultGridItemTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid >
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition/>
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Grid.Column" Value="{Binding Col}"/>
<Setter Property="Grid.Row" Value="{Binding Row}"/>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
C#
public class FilterItem
{
public int id_node { get; set; }
public int id_h { get; set; }
//[MaxLength(50)]
public string name { get; set; }
public int Col { get; set; }
public int Row { get; set; }
}
Unfortunately that will not work since there is nothing to bind to as the container isn't in XAML. What you have to do is subclass the ItemsControl and override the PrepareContainerForItemOverride function like so:
public class CustomItemsControl : ItemsControl
{
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
base.PrepareContainerForItemOverride(element, item);
FrameworkElement source = element as FrameworkElement;
source.SetBinding(Grid.ColumnProperty, new Binding { Path = new PropertyPath("Col") });
source.SetBinding(Grid.RowProperty, new Binding { Path = new PropertyPath("Row") });
}
}
Then change your XAML to your CustomItemsControl instead of the items control:
<local:CustomItemsControl x:Name="ItControl" ItemTemplate="{StaticResource DefaultGridItemTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid >
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition/>
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!--<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Grid.Column" Value="{Binding Col}" />
<Setter Property="Grid.Row" Value="{Binding Row}"/>
</Style>
</ItemsControl.ItemContainerStyle>-->
</local:CustomItemsControl>
try to add the main ItemsControl inside StackPanel with Orientation vertical.
Thanks
Related
I've got a ListBox in WPF where I'm adding items through an OpenFileDialog. Here the Code where I add the Items to my ListBox. (tbxFiles = my listbox name)
if (openFileDialog.ShowDialog() == true)
{
foreach (string filename in openFileDialog.FileNames)
{
path.Add(filename);
for (int i = 0; i < path.Count; i++)
{
tbxFiles.Items.Add(path[i]);
}
}
var _items = this.tbxFiles.Items.Cast<string>().Distinct().ToArray();
this.tbxFiles.Items.Clear();
foreach (var item in _items)
{
this.tbxFiles.Items.Add(item);
}
}
When I look at the breakpoint I can see that the content of what I added to my ListBox is correct. The problem starts showing as I added this DataTemplate to my ListBox:
<ListBox Grid.Column="1" BorderBrush="Black" Margin="15,20,31,15" MinHeight="25" Name="tbxFiles" VerticalAlignment="Stretch" ItemsSource="{Binding Items}" SelectionMode="Multiple">
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="ListText" Grid.Column="0"/>
<RadioButton Grid.Column="1" Content="TF" />
<RadioButton Grid.Column="2" Content="AF" />
<ComboBox Grid.Column="3" Text="Periode" />
<Button Grid.Column="4" Click="RemoveMark_Click" Content="Delete" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.Resources>
</ListBox>
The moment I added this DataTemplate it stopped showing me the text, even when I remove the Items from the DataTemplate it isn't showing anything. Maybe I should start showing the text in the textbox I created, but I cannot adress it's name because it is in a DataTemplate. Have any of you an idea of how I can show the name I want to have in the ListBox?
Use binding for your ListBox,
change XAML source to:
<ListBox Grid.Column="1" BorderBrush="Black" Margin="15,20,31,15" MinHeight="25" Name="tbxFiles"
VerticalAlignment="Stretch"
ItemsSource="{Binding Items}"
SelectionMode="Multiple">
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="ListText" Grid.Column="0" Text="{Binding FileName}"/>
<RadioButton Grid.Column="1" Content="TF" />
<RadioButton Grid.Column="2" Content="AF" />
<ComboBox Grid.Column="3" Text="Periode" />
<Button Grid.Column="4" Click="RemoveMark_Click" Content="Delete" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.Resources>
</ListBox>
and add two View model classes:
public class ViewModel
{
public List<FileItem> Items { get; set; }
}
public class FileItem
{
public string FileName { get; set; }
}
and you may bind loading file names to your ListBox like this:
var vm = new ViewModel();
vm.Items = new List<FileItem>();
if (openFileDialog.ShowDialog() == true)
{
foreach (string filename in openFileDialog.FileNames)
{
vm.Items.Add(new FileItem { FileName = filename });
}
tbxFiles.DataContext = vm;
}
In a proper MVVM approach you would however have a view model like this:
public class ViewModel
{
public ObservableCollection<FileItem> Items { get; }
= new ObservableCollection<FileItem>();
}
with a readonly ObservableCollection property, which is once assigned to the DataContext of the Window, e.g. like
private readonly ViewModel viewModel = new ViewModel();
public MainWindow()
{
InitializeComponent();
DataContext = viewModel;
}
and used like this:
if (openFileDialog.ShowDialog() == true)
{
viewModel.Items.Clear();
foreach (string filename in openFileDialog.FileNames)
{
viewModel.Items.Add(new FileItem { FileName = filename });
}
}
I would like to arrange my items in a ListView with a Text and an image like in this example:
The first column is automatic, so it expands to the widest element.
The second column should expand to fill the remaining space.
So, how can I make an Auto column... or simulate it?
Obviously, the difficult part of this layout is that different elements have their widths depending on other element's widths.
EDIT: Using #WPInfo's answer, I've tried with this:
XAML
<Page.DataContext>
<local:MainViewModel></local:MainViewModel>
</Page.DataContext>
<ListView ItemsSource="{Binding Items}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding}" />
<Border Background="CornflowerBlue" Grid.Column="1" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
CODE:
public class MainViewModel
{
public IList<string> Items { get; }
public MainViewModel()
{
Items = new List<string>()
{
"ABC",
"ABCDEF",
"ABCDEFGHI",
};
}
}
The expected result was:
However, the actual result is:
The goal is that the first column to be as wide as the widest element inside it.
In WPF, this is solved easily with the use of Grid.SharedSizeGroup. In UWP there is not such a thing.
The problem is that ListView children don't know anything about each other. There's no simple trick to have all the items know what the longest text item is, so a more complicated solution is required. The following works. It will determine a fixed TextBlock size based on the largest item from the string list, and it will update it should the font size change. Obviously a simpler solution closer resembling your example code can be had if you decide on a fixed column size for either the text or the image, but I assume you already know that.
XAML:
<Page.DataContext>
<local:MainViewModel></local:MainViewModel>
</Page.DataContext>
<ListView ItemsSource="{Binding Items}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding MyText, Mode=OneWay}" FontSize="{Binding ItemFontSize, Mode=OneWay}" Width="{Binding TextWidth, Mode=OneWay}" />
<Border Background="CornflowerBlue" Grid.Column="1" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
C# ViewModel
public class MainViewModel : INotifyPropertyChanged
{
public ObservableCollection<MyListViewItemsClass> Items { get; set; }
private List<string> ItemsFromModel;
private int _myFontSize;
public int MyFontSize
{
get { return _myFontSize; }
set
{
if (value != _myFontSize)
{
_myFontSize = value;
OnPropertyChanged("MyFontSize");
// Font size changed, need to refresh ListView items
LoadRefreshMyListViewItems();
}
}
}
public MainViewModel()
{
// set default font size
_myFontSize = 20;
// example data
ItemsFromModel = new List<string>()
{
"ABC",
"ABCDEF",
"ABCDEFGHI",
};
LoadRefreshMyListViewItems();
}
public void LoadRefreshMyListViewItems()
{
int itemMaxTextLength = 0;
foreach (var modelItem in ItemsFromModel)
{
if (modelItem.Length > itemMaxTextLength) { itemMaxTextLength = modelItem.Length; }
}
Items = new ObservableCollection<MyListViewItemsClass>();
// Convert points to pixels, multiply by max character length to determine fixed textblock width
// This assumes 96 DPI. Search for how to grab system DPI in C# there are answers on SO.
double width = MyFontSize * 0.75 * itemMaxTextLength;
foreach (var itemFromModel in ItemsFromModel)
{
var item = new MyListViewItemsClass();
item.MyText = itemFromModel;
item.ItemFontSize = MyFontSize;
item.TextWidth = width;
Items.Add(item);
}
OnPropertyChanged("Items");
}
public class MyListViewItemsClass
{
public string MyText { get; set; }
public int ItemFontSize { get; set; }
public double TextWidth { get; set; }
}
protected void OnPropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, e);
}
public void OnPropertyChanged(string propertyName)
{
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
Try setting ItemContainerStyle property for the ListView:
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
Then your ListView may look like this:
<ListView x:Name="list">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock ... />
<Image Grid.Column="1" HorizontalAlignment="Right" ... />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
After that, you can set a proper value for HorizontalAlignment property of your ListView.
I have following UserControl :
<Grid x:Name="LayoutRoot">
<CheckBox x:Name="seat" Margin="2,2,2,2.901" BorderBrush="#FF003FFF" Content="{Binding Path=TypeSSeat, ElementName=UserControl}" />
</Grid>
With This CodeBehind :
[DefaultValue(Nothing)]
public enum TypeSeat
{
Nothing,FirstClass, businessclass , economyclass ,NoSeat
}
public partial class UCSeat : UserControl
{
public TypeSeat TypeSSeat
{
get
{
return (TypeSeat)GetValue(ItemTextProperty);
}
set
{
SetValue(ItemTextProperty, value);
}
}
public static readonly DependencyProperty ItemTextProperty =
DependencyProperty.Register("TypeSSeat", typeof(TypeSeat), typeof(UCSeat), new PropertyMetadata(default(TypeSeat)));
i want to fill itemscontrol with this usercontrol but after run i have just one checkBox.
this is my windows code :
<ItemsControl Name="icName" Height="366" VerticalAlignment="Top" ItemsSource="{Binding Path=UCSeat}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="0,0,0,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<local:UCSeat HorizontalAlignment="Left" Width="156.8" TypeSSeat="{Binding seat1}" ToolTip="1"/>
<local:UCSeat HorizontalAlignment="Left" Width="156.8" TypeSSeat="{Binding seat2}" ToolTip="2"/>
and with this code behind :
List<SeatList> lst = new List<SeatList>();
lst.Add(new SeatList { seat1 = TypeSeat.FirstClass, seat2 = TypeSeat.FirstClass, seat3 = TypeSeat.NoSeat, seat4 = TypeSeat.FirstClass, seat5 = TypeSeat.FirstClass, seat6 = TypeSeat.Nothing, seat7 = TypeSeat.Nothing, seat8 = TypeSeat.Nothing, seat9 = TypeSeat.Nothing, seat10 = TypeSeat.Nothing, seat11 = TypeSeat.Nothing, seat12 = TypeSeat.Nothing, seat13 = TypeSeat.Nothing, seat14 = TypeSeat.Nothing });
icName.ItemsSource = lst;
Your DataTemplate uses a grid as it's layout control. The two UCSeat user controls are placed in this grid without specifying which column they should be located in.
This means both UCSeat controls are placed on top of each other which might make it look as if only one checkbox is being displayed.
Either change the second UCSeat entry to include the Grid.Column="1" to make the second user control show in the second column
OR use a StackPanel container with Orientation="Horizontal" instead of the Grid container meaning both will layout horizontally automatically
You have all the items there, however they are all stacked on top of each other.
To properly layout items you need to set your ItemsPanelTemplate to whatever container you are placing your items in (such as a Grid), and use the ItemContainerStyle to set any specific properties of your items (such as Grid.Row and Grid.Column
Here's some sample XAML taken from my blog post about the ItemsControl
<ItemsControl ItemsSource="{Binding MyCollection}">
<!-- ItemsPanelTemplate -->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- ItemContainerStyle -->
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Grid.Column"
Value="{Binding ColumnIndex}" />
<Setter Property="Grid.Row"
Value="{Binding RowIndex}" />
</Style>
</ItemsControl.ItemContainerStyle>
<!-- ItemTemplate -->
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
This assumes you are binding to a collection of objects that look something like this :
public class MyObjectModel
{
public string Name { get; set; }
public int ColumnIndex{ get; set; }
public int RowIndex{ get; set; }
}
And results in something like this :
I'd highly recommend reading the actual post as well if you're new to using an ItemsControl :)
I have a problem displaying a large dataset (around 27k elements). The problem is that after a certain point items would not display anymore but would still be be clickable. In fact, the items would display when scrolling but would disappear as soon as the scrolling stops. After some testing I found out it was stopping rendering after the 2^21 pixel. Complexity of the objects being rendered do not seem to affect this limit.
I have made a sample project to illustrate this:
In a blank windows store app, replace MainPage.xaml default grid with this one
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"></RowDefinition>
<RowDefinition Height="24"></RowDefinition>
<RowDefinition Height="24"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock x:Name="textblock" Grid.Row="2"></TextBlock>
<Button Grid.Column="0" Grid.Row="1" Tapped="Button_Tapped"></Button>
<Button Grid.Column="1" Grid.Row="1" Tapped="Button_Tapped_1"></Button>
<Button Grid.Column="2" Grid.Row="1" Tapped="Button_Tapped_2"></Button>
<Button Grid.Column="3" Grid.Row="1" Tapped="Button_Tapped_3"></Button>
<ListView Grid.Column="0" Background="Red" x:Name="simpleList1" SelectionChanged="list_SelectionChanged">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Margin" Value="0,0,0,-8" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid Height="100">
<TextBlock Text="{Binding Index}"></TextBlock>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ListView Grid.Column="1" Background="DarkGoldenrod" x:Name="simpleList2" SelectionChanged="list_SelectionChanged">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Margin" Value="0,0,0,-8" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid Height="250">
<TextBlock Text="{Binding Index}"></TextBlock>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ListView Grid.Column="2" Background="Blue" x:Name="complexList1" SelectionChanged="list_SelectionChanged">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Margin" Value="0,0,0,-8" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid Height="333">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="{Binding SimpleItem.Index}"></TextBlock>
<TextBlock Grid.Row="1" Text="{Binding ShortMsg}"></TextBlock>
<TextBlock Grid.Row="2" Text="{Binding RandomNumber}"></TextBlock>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ListView Grid.Column="3" Background="Violet" x:Name="complexList2" SelectionChanged="list_SelectionChanged">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Left" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Margin" Value="0,0,0,-8" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid Height="500">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="{Binding SimpleItem.Index}"></TextBlock>
<TextBlock Grid.Row="1" Text="{Binding ShortMsg}"></TextBlock>
<TextBlock Grid.Row="2" Text="{Binding RandomNumber}"></TextBlock>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
And in the MainPage.xaml.cs
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public class SimpleItem
{
public int Index { get; set; }
public SimpleItem(int index)
{
Index = index;
}
public override string ToString()
{
return "I am a simple item with index " + Index;
}
}
public class ComplexItem
{
static Random rand = new Random();
public SimpleItem SimpleItem { get; set; }
public string ShortMsg { get; set; }
public double RandomNumber { get; set; }
public ComplexItem(int index)
{
SimpleItem = new SimpleItem(index);
ShortMsg = "My simple item has index " + SimpleItem.Index;
RandomNumber = rand.NextDouble() * (double)SimpleItem.Index;
}
public override string ToString()
{
return "I am a complex item with index " + SimpleItem.Index;
}
}
public ObservableCollection<SimpleItem> listSI = new ObservableCollection<SimpleItem>();
public ObservableCollection<ComplexItem> listCI = new ObservableCollection<ComplexItem>();
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
InitializeLists();
simpleList1.ItemsSource = listSI;
simpleList2.ItemsSource = listSI;
complexList1.ItemsSource = listCI;
complexList2.ItemsSource = listCI;
}
private void InitializeLists()
{
for (int i = 0; i < 2000000; ++i)
{
listSI.Add(new SimpleItem(i));
listCI.Add(new ComplexItem(i));
}
}
private void Button_Tapped(object sender, TappedRoutedEventArgs e)
{
int target = (int)Math.Pow(2, 21);
int heigthPerItem = 100;
SimpleItem item = listSI[target / heigthPerItem];
simpleList1.ScrollIntoView(item);
}
private void Button_Tapped_1(object sender, TappedRoutedEventArgs e)
{
int target = (int)Math.Pow(2, 21);
int heigthPerItem = 250;
SimpleItem item = listSI[target / heigthPerItem];
simpleList2.ScrollIntoView(item);
}
private void Button_Tapped_2(object sender, TappedRoutedEventArgs e)
{
int target = (int)Math.Pow(2, 21);
int heigthPerItem = 333;
ComplexItem item = listCI[target / heigthPerItem];
complexList1.ScrollIntoView(item);
}
private void Button_Tapped_3(object sender, TappedRoutedEventArgs e)
{
int target = (int)Math.Pow(2, 21);
int heigthPerItem = 500;
ComplexItem item = listCI[target / heigthPerItem];
complexList2.ScrollIntoView(item);
}
private void list_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 0)
{
string text = e.AddedItems[0].ToString();
textblock.Text = text;
}
}
}
This should be the result (with some info how to use it) : ListViewBugInterface
This person had the same problem as me and says it fixed it by using a VirtualizingStackPanel, but this shouldn't be needed since windows 8.1.
I doubt it is a UI virtualization problem since the ListViews scroll smoothly, the items start appearing when scrolling and can be tapped/clicked.
Anyone had this behavior? Am I missing the obvious? (e.g: to not have a dataset of 27k items) Anyone knows a solution to make the items render after the 2^21 pixel?
TLDR:
When displaying pixels after 2^21 pixels of combined ListViewItem they stop being rendered but can still be clicked. How do I fix this?
I was working on creating a reusable custom control (not a user control) in WPF. I created the XAML in the Themes/Generic.xaml file and I setup the "lookless" functionality in the control's CS file:
AddressField.cs
using ...;
namespace MyNamespace
{
[TemplatePart(Name = AddressField.ElementAddress1TextBox, Type = typeof(TextBox))]
public class AddressField : Control
{
private const String ElementAddress1TextBox = "PART_Address1TextBox";
public AddressEntity Address
{
get { return (AddressEntity)GetValue(AddressProperty); }
set { SetValue(AddressProperty, value); }
}
public static readonly DependencyProperty AddressProperty =
DependencyProperty.Register("Address", typeof(AddressEntity), typeof(AddressField), new UIPropertyMetadata(null, new PropertyChangedCallback(OnAddressPropertyChangedCallback)));
static AddressField()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(AddressField), new FrameworkPropertyMetadata(typeof(AddressField)));
}
}
}
Themes\Generic.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyNamespace"
>
<Style TargetType="{x:Type local:AddressField}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:AddressField}">
<StackPanel>
<Grid x:Name="StandardView">
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="Height" Value="17" />
<Setter Property="Margin" Value="3,3,3,3" />
</Style>
<Style TargetType="TextBox">
<Setter Property="Height" Value="23" />
<Setter Property="Margin" Value="3,3,3,3" />
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- Address 1, Address2-->
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Text="Address:" TextWrapping="NoWrap" />
<TextBox Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="8" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" MinWidth="300"
x:Name="PART_Address1TextBox" Text="{Binding Path=Address1}" />
</Grid>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Form.xaml
<Window x:Class="NIC.BackOffice.Casino.RegistrationEntryForm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:nic="clr-namespace:MyNamespace;assembly=MyStuff">
<Canvas>
<nic:AddressField Canvas.Left="10" Canvas.Top="10"
x:Name="OfficeAddressField" Address={Binding Path=OAddress} />
</Canvas>
</Window>
Form.cs
using ...;
namespace MyNamespace
{
public partial class Form : Window
{
public Form()
{
InitializeComponent();
OAddress = new AddressEntity("1234 Testing Lane");
}
public AddressEntity OAddress { get; set; }
}
}
UPDATED: The prior code is an update from my previous code (removed a lotta fluff just to get down to the ONE example). Though, for some reason Address (within OfficeAddressField) is never ever updated even though I set the binding of OAddress to the AddressField object.
You don't need to refresh the DataContext. In fact, your control shouldn't be using it. Make Address a DependencyProperty and then use a TemplateBinding in your control's template:
<TextBox Text="{TemplateBinding Address.Address1}"/>
You should consider raising an event when the address dp changes.