I am developing an application where I have a class called UIManager in which there is a method which has an array of data
public void DisplayCatalog(string[] displayName, BitmapImage[] icons)
{
DisplayItem.Clear();
for (int i = 0; i < displayName.Length; i++)
{
DisplayItem.Add(new ItemList { WidgetName = displayName[i], Icon = icons[i] });
}
NotifyPropertyChanged("UI");
}
Now I want this data ie;WidgetName to be displayed in my MainPage where I have used a Looping selector.
*<custom:LoopingSelector x:Name="selectorLeft" ItemMargin="5" ItemSize="145,145" Margin="6,0,-6,22">
<custom:LoopingSelector.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding WidgetName}"/>
</StackPanel>
</DataTemplate>
</custom:LoopingSelector.ItemTemplate>
</custom:LoopingSelector>
*
Also I need to scroll the looping selector Horizontally.
How can I achieve this...??? Any valuable solutions Please.......
I have used Horizontal Looping Selector but I am not getting how to bind the data from my UIManager class on to the Horizontal Looping Selector..
<toolkit:HorizontalLoopingSelector Grid.Row="0" Margin="12" Height="128" ItemSize="128,128" ItemTemplate="{StaticResource ?????}">
<toolkit:HorizontalLoopingSelector.DataSource>
????????
</toolkit:HorizontalLoopingSelector.DataSource>
</toolkit:HorizontalLoopingSelector>
u need to create a datasource class and bind the values to the looping selector source .its similar to binding source to the vertical looping selector.
Visit http://www.windowsphonegeek.com/articles/WP7-LoopingSelector-in-depth--Part1-Visual-structure-and-API
Check out this resource if you still require a horizontal loop selector:
http://blog.supaywasi.com/2011/06/horizontal-looping-selector/
Related
I am developing a program within UWP that will have the ability to chart data on-screen, and must support the potential that a user may want to chart a large number of series on it.
The Chart that I am using is Telerik's RadCartesianChart and I am using a RadLegendControl for showing the legend for the chart. This is laid out on a Grid that has two Columns and one Row. In the first Column (0) is the RadLegendControl. In the second Column (1) is the RadCartesianChart.
When a large number of Series are drawn, this can result in the Legend going down below the bottom of the app, cutting off the remaining items in the legend. This is basically an "excessive" example of the usage of this chart and I'm wanting to make sure it can function effectively when put under this kind of use.
Is there a way to add a scrollbar to the Legend Control so that a user can scroll through the legend? Or should I be looking at a different method for showing the legend?
This is for a program made within UWP that is currently targeting a minimum version of Windows 10 1803 and aiming for 1809, using Visual Studio 2019.
I made a post over on Telerik's forum asking this question and it was suggested that there is possibly an external component that is letting the legend extend to its full height off-screen and they provided a possible solution in trying to set an explicit maximum height to see the scrollbar appear when it reaches that upper bound. As such, in the XAML I set MaxHeight="300", which is much smaller than the average Chart's legend would require, such that I could easily see if the Scrollbar appeared. When I tried this, no Scrollbar appeared.
Originally I was having the RadLegendControl being drawn utilising a StackPanel to reorder the Legend to display from top-down instead of left-to-right so that it could fit alongside the Chart. I suspected that the StackPanel's internal ScrollViewer may have been conflicting with the RadLegendControl's internal ScrollViewer. I removed the StackPanel layout to ensure that it could not conflict to see if a ScrollViewer would then appear. It did not (I tested a horizontal one as well, to no success).
I have tried other solutions such as binding the MaxHeight property of the RadLegendControl to the Height or ActualHeight of the Grid row that it is on, explicitly setting VerticalScrollMode to Enabled and VerticalScrollVisibility to Visible.
This is the RadLegendControl code within XAML, still with the MaxHeight set explicitly to 300:
<telerikPrimitives:RadLegendControl
x:Name="LegendForChart"
LegendProvider="{Binding ElementName=MainChart}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Top"
MaxHeight="300"
>
<telerikPrimitives:RadLegendControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</telerikPrimitives:RadLegendControl.ItemsPanel>
</telerikPrimitives:RadLegendControl>
Where telerikPrimitives is defined with the following:
xmlns:telerikPrimitives="using:Telerik.UI.Xaml.Controls.Primitives"
I have tried adding/modifying the following lines:
MaxHeight="{Binding ElementName=ChartGrid, Path=Height, Mode=Oneway}"
MaxHeight="{Binding ElementName=ChartGrid, Path=ActualHeight, Mode=Oneway}"
ScrollViewer.VerticalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollMode="Enabled"
Currently with my file that can display ~332 Series on my Chart, the Legend does not have a Scrollbar showing, with the items disappearing off-screen. (Unfortunately I don't have enough rep to show an image).
I would like to find a solution where, if there are sufficient Series showing, a vertical Scrollbar would appear and allow the user to scroll down through the Legend.
I realise this may appear as excessive, but I would like to ensure that my program behaves appropriately if a user would, for any reason, decide to display a large number of Series on the chart.
Since you just provide the RadLegendControl XAML code, I did not see your whole XAML code sample. I'm not sure what the issue is on your side.
So, I made a simple code sample according to the Telerik's official document.
I just use a ScrollViewer control to wrap the RadLegendControl, then it will be scrollable.
Please see my code sample:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"></ColumnDefinition>
<ColumnDefinition Width="8*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<telerikChart:RadCartesianChart x:Name="chart" Grid.Column="1">
<telerikChart:RadCartesianChart.HorizontalAxis>
<telerikChart:CategoricalAxis />
</telerikChart:RadCartesianChart.HorizontalAxis>
<telerikChart:RadCartesianChart.VerticalAxis>
<telerikChart:LinearAxis />
</telerikChart:RadCartesianChart.VerticalAxis>
<telerikChart:RadCartesianChart.SeriesProvider>
<telerikChart:ChartSeriesProvider x:Name="provider">
<telerikChart:ChartSeriesProvider.SeriesDescriptors>
<telerikChart:CategoricalSeriesDescriptor ItemsSourcePath="GetData" ValuePath="Value" CategoryPath="Category" LegendTitlePath="LegendTitle">
<telerikChart:CategoricalSeriesDescriptor.Style>
<Style TargetType="telerikChart:BarSeries">
<Setter Property="CombineMode" Value="Cluster" />
</Style>
</telerikChart:CategoricalSeriesDescriptor.Style>
</telerikChart:CategoricalSeriesDescriptor>
</telerikChart:ChartSeriesProvider.SeriesDescriptors>
</telerikChart:ChartSeriesProvider>
</telerikChart:RadCartesianChart.SeriesProvider>
</telerikChart:RadCartesianChart>
<ScrollViewer>
<telerikPrimitives:RadLegendControl x:Name="LegendForChart" LegendProvider="{Binding ElementName=chart}">
<telerikPrimitives:RadLegendControl.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</telerikPrimitives:RadLegendControl.ItemsPanel>
</telerikPrimitives:RadLegendControl>
</ScrollViewer>
</Grid>
private Random r = new Random();
public List<ViewModel> GenerateCollection()
{
List<ViewModel> collection = new List<ViewModel>();
for (int i = 0; i < 500; i++)
{
ViewModel vm = new ViewModel();
vm.GetData = GenerateData();
vm.LegendTitle = "ViewModel " + i;
collection.Add(vm);
}
return collection;
}
public List<Data> GenerateData()
{
List<Data> data = new List<Data>();
data.Add(new Data { Category = "Apple", Value = r.Next(1, 20) });
data.Add(new Data { Category = "Orange", Value = r.Next(10, 30) });
data.Add(new Data { Category = "Lemon", Value = r.Next(20, 40) });
return data;
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
this.provider.Source = GenerateCollection();
}
public class ViewModel
{
public List<Data> GetData { get; set; }
public string LegendTitle { get; set; }
}
public class Data
{
public double Value { get; set; }
public string Category { get; set; }
}
I have a Pivot where I set the header in my Pivot.HeaderTemplate it is basically just showing Names of Books. In my Pivot.ItemTemplate I want to show a Grid which is build in my .xaml.cs but since the Grid is in my DataTemplate I can not access the Grid x:Name anymore in the code behind in .xaml.cs. books is a Collection of Books which contains a Name and a Title
MainPage.xaml
<Pivot ItemsSource="{x:Bind books}">
<Pivot.HeaderTemplate>
<DataTemplate x:DataType="local:Book">
<TextBlock Text="{x:Bind Name}"/>
</DataTemplate>
</Pivot.HeaderTemplate>
<Pivot.ItemTemplate>
<DataTemplate>
<Grid
x:Name="BooksGrid"
BorderBrush="Black" BorderThickness="1 1 0 0"
Margin="0 10 0 0>
</Grid>
</DataTemplate>
</Pivot.ItemTemplate>
Now I want to acces BooksGrid iny the code behind and actually create the Grid
MainPage.xaml.cs
public MainPage()
{
this.InitializeComponent();
}
private void DrawGrid()
{
//create columns of Grid
for (int i = 0; i < booksize.XProperties.Count + 1; i++)
{
BooksGrid.ColumnDefinitions.Add(new ColumnDefinition
{
});
}
BooksGrid.ColumnDefinitions[0].Width = GridLength.Auto;
}
....
Already here at BooksGrid.ColumnDefinitions.Add(...) I get the error that BooksGrid can not be found.
My DrawGrid works if I do not place the Grid definition in my DataTemplate and also outside myPivot. So the MainPage.xaml.csdoes not find it when the Grid is inside my DataTemplate
I've read that the solution might be that I have to acces the Grid instance that I want to work with, as soon as the DataTemplate gets loaded. But I do not know how to do that either.
EDIT PART to first solution:
I'm also using BooksGrid in another method
MainPage.xaml.cs
private void DrawBooksFront(Front front)
{
int row;
int column;
column = booksize.XProperties.IndexOf(front.CustomProps[booksize.XLabel])+1;
row = booksize.YProperties.IndexOf(front.CustomProps[booksize.YLabel])+1;
Frame newFrame = new Frame();
TaskBoardGrid.Children.Add(newFrame);
Grid.SetColumn(newFrame, column);
Grid.SetRow(newFrame, row);
}
The reason you cannot access your BooksGrid is because it will be dynamically generated for each book in the books collection. So for every book a Grid will be generated.
OPTION 1:
You can add a Loaded event to your grid:
<Pivot x:Name="Pivot" ItemsSource="{x:Bind books}">
<Pivot.HeaderTemplate>
<DataTemplate x:DataType="local:Book">
<TextBlock Text="{x:Bind Name}"/>
</DataTemplate>
</Pivot.HeaderTemplate>
<Pivot.ItemTemplate>
<DataTemplate>
<Grid
BorderBrush="Black" BorderThickness="1,1,0,0"
Margin="0,10,0,0" Loaded="DrawGrid">
</Grid>
</DataTemplate>
</Pivot.ItemTemplate>
and in your code behind:
private void DrawGrid(object sender, RoutedEventArgs e)
{
Grid grid = sender as Grid;
// Load your grid..
}
EDIT - OPTION 2:
If you'd like to access your grids from code behind in a different way (like suggested in your edit) you can always do the following:
private void DrawBooksFront(Front front)
{
// Loop through the pivot's items and get the content from each item's ContentTemplate.
foreach (var item in Pivot.Items)
{
PivotItem pivotItem = Pivot.ContainerFromItem(item) as PivotItem;
Grid grid = pivotItem.ContentTemplate.LoadContent() as Grid;
// Do something with the grid.
}
}
If your goal is to display previews of the pages of the book inside a PivotItem in a grid-like manner [picture below], then you're better off placing GridView in a DataTemplate of Pivot.ItemTemplate and using data binding to display those pages automatically, this would eliminate the need to write the code in xaml.cs that you showed.
Please, share more details about your app (what you're given and what the end result should look like) so we could help you better.
I want to be able to say:
Get the first textblock, then the first checkbox, both with the number 1 in their name.
Then if the checkbox is checked, then the textblock can be populated.
See code:
for (int i = 1; i < 10; i++)
{
TextBlock a = (this.FindName(string.Format("tb_{0}", i)) as TextBlock);
CheckBox b = (this.FindName(string.Format("ck_{0}", i)) as CheckBox);
if (b.IsChecked.HasValue)
{
if (a != null) a.Text = data.ArrayOfSensors[i].ToString();
}
else
{
if (a != null) a.Text = data.ArrayOfSensors[0].ToString();
}
}
So when the checkbox is enabled, the textblock will be populated with the index from the array.
Many thanks!
EDIT: A slightly better explanation:
The textblocks are named: tb_1, tb_2 etc
The Checkboxes are named: cb_1, cb_2 etc
The array is:
[0] 0
[1] 100
[2] 150
The number is what they all have in common. So I can use a for loop with i as a common variable for each. I also have about 50 textboxes and Comboboxes and don't want to write each one out individually.
EDIT: My ComboBoxes and Textblocks are created on Xaml code like this:
<CheckBox x:Name="Cb_1" Width="15" Height="15" Margin="349,53,127,164" IsChecked="True" />
<TextBlock x:Name="tb_1" Text="80" Height="20" Width="20" Margin="266,35,205,177" />
Its hard to answer without seeing what your XAML looks like, however it sounds like you may be trying to use WPF like it is WinFirms.
To build an interface like this in WPF, you should start by creating a custom class to hold your data, and then use an ItemsControl to render your collection of data.
For example, your class might look something like this
public class SensorData() : INotifyPropertyChanged
{
// should implement INotifyPropertyChanged of course
public string Text { get; set; }
public bool IsChecked { get; set; }
}
And an ObservableCollection<SensorData> might be rendered using an <ItemsControl> with a ItemsPanelTemplate containing both a CheckBox and a TextBox
<ItemsControl ItemsSource="{Binding MyCollectionOfSensorData}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Checked="{Binding IsChecked}" />
<TextBlock Text="{Binding Text}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
This will loop through the collection of SensorData objects, and render a CheckBox and TextBox for each one. If you want to do any manipulation of the data from the code-behind, you only need to modify the properties of the SensorData objects.
For example, you could have a loop that goes
for (int i = 0; i < MyCollectionOfSensorData.Length; i++)
{
SensorData item = MyCollectionOfSensorData[i];
if (item.IsChecked)
item.Text = data.ArrayOfSensors[i].ToString();
else
item.Text = "0";
}
And there would be no interaction with the UI objects at all.
I have two controls in a Stack Panel - Map and TextBlock. Collection of pushpins on a map changes dynamically. So I need TextBlock to display current Count of items in pushpins collection.
What is a right approach to bind ItemsSource.Length to TextBlock.Text? Somehow like this:
<maps:Map Name="MainMap">
<toolkit:MapExtensions.Children>
<toolkit:MapItemsControl Name="BusItems">
<toolkit:MapItemsControl.ItemTemplate>
<DataTemplate>
<toolkit:Pushpin GeoCoordinate="{Binding Coordinates}" Content="{Binding Value}"/>
</DataTemplate>
</toolkit:MapItemsControl.ItemTemplate>
</toolkit:MapItemsControl>
</toolkit:MapExtensions.Children>
</maps:Map>
<TextBlock Text="{Binding Items.Count, ElementName=BusItems}"></TextBlock>
You cannot bind to Items.Count, because it is a method not a property, so create a property exposing Items.Count() like so:
public int PushpinCount
{
get { return Items.Count(); }
}
and bind to PushpinCount instead.
Simple question but I am totally confused. I am developing a wp7 app using C#. I want a listbox with input number of image item which source should be same i.e. the list box should contain 'n' Image control with source set to a single image where 'n' is number of Listbox Item enter by user. e.g. If the user input '10', then the listbox should have ten items. I want the listbox ItemsPanelTemplate as Wrap-panel. Can somebody suggest me how to get this?
Define a ListBox in your XAML something like this
<ListBox x:Name="ListBoxImages">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Image Source="{Binding Imagesource}" Width="300"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
and then set its Source in the code behind like this
int noOfImages = 10; //Take the input from user
List<ImageClass> imageList = new List<ImageClass>();
for(int i=0; i<noOfImages; i++)
imageList.Add(new ImageClass() { Imagesource = "/user.jpg" });
ListBoxImages.ItemsSource = imageList; //Set the source of the listbox here
where ImageClass is,
public class ImageClass
{
public String Imagesource { get; set; }
}
The above is a sample for your understanding. Please customize wisely to suit your needs