Issues displaying 2 seperate Canvases at the same time in XAML - c#

I have canvas A and canvas B.
Canvas A contains an Image and a grid with diffrent colour squares.
numSelectCan is a diffrent image.
Once i click on a square a event triggers that should set the visibilty state of numSelectCan to visible and then it should show up overlaping Canvas A.
That is not the case. I have tryed everything but i cant get numSelectCan to show up at all.
During development numSelectCan is displayed and works fine. At runtime numSelectCan is just gone. I tryed disabling A but still no success.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="10,0,10,10">
<Controls:RoundButton x:Name="btnCancel" PressedBrush="Orange" Foreground="White" BorderBrush="White" ImageSource="/Assets/Appgraphics/Buttons/cancel.png" HorizontalAlignment="Left" VerticalAlignment="Bottom" Click="btnCancel_Click"/>
<Controls:RoundButton x:Name="btnQuestion" PressedBrush="Orange" Foreground="White" ImageSource="/Assets/Appgraphics/Buttons/questionmark.png" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,10,0,0" Click="btnQuestion_Click" BorderBrush="White"/>
<Controls:RoundButton x:Name="btnConfirm" PressedBrush="Orange" Foreground="White" BorderBrush="White" ImageSource="/Assets/Appgraphics/Buttons/check.png" HorizontalAlignment="Right" VerticalAlignment="Bottom" Click="confirmSelection"/>
<Canvas x:Name="picCanvas" HorizontalAlignment="Center" Width="582" Height="320">
<Image x:Name="imgBackCC" Height="320" Width="582" Stretch="Fill" HorizontalAlignment="Center" Source="" Margin="0,0,0,0"/>
</Canvas>
<Canvas x:Name="numSelectCan" HorizontalAlignment="Center" Height="155" Visibility="Visible" Width="530" VerticalAlignment="Center">
<Image x:Name="numSelBackground" Source="/Assets/Appgraphics/UserInterface/numFieldBackground.png" Height="155" Width="530" Stretch="Fill"/>
<Image x:Name="numFieldButton1" Source="/Assets/Appgraphics/UserInterface/numField0.png" Width="70" Height="70" Canvas.Left="5" Canvas.Top="5"/>
<Image x:Name="numFieldButton2" Source="/Assets/Appgraphics/UserInterface/numField1.png" Width="70" Height="70" Canvas.Left="80" Canvas.Top="5"/>
<Image x:Name="numFieldButton3" Source="/Assets/Appgraphics/UserInterface/numField2.png" Width="70" Height="70" Canvas.Left="155" Canvas.Top="5"/>
<Image x:Name="numFieldButton4" Source="/Assets/Appgraphics/UserInterface/numField3.png" Width="70" Height="70" Canvas.Left="230" Canvas.Top="5"/>
<Image x:Name="numFieldButton5" Source="/Assets/Appgraphics/UserInterface/numField4.png" Width="70" Height="70" Canvas.Left="305" Canvas.Top="5"/>
<Image x:Name="numFieldButton6" Source="/Assets/Appgraphics/UserInterface/numField5.png" Width="70" Height="70" Canvas.Top="80" Canvas.Left="5"/>
<Image x:Name="numFieldButton7" Source="/Assets/Appgraphics/UserInterface/numField6.png" Width="70" Height="70" Canvas.Left="80" Canvas.Top="80"/>
<Image x:Name="numFieldButton8" Source="/Assets/Appgraphics/UserInterface/numField7.png" Width="70" Height="70" Canvas.Left="155" Canvas.Top="80"/>
<Image x:Name="numFieldButton9" Source="/Assets/Appgraphics/UserInterface/numField8.png" Width="70" Height="70" Canvas.Left="230" Canvas.Top="80"/>
<Image x:Name="numFieldButton10" Source="/Assets/Appgraphics/UserInterface/numField9.png" Width="70" Height="70" Canvas.Left="305" Canvas.Top="80"/>
<Image x:Name="numFieldDelButton" Source="/Assets/appgraphics/UserInterface/numFieldDelete.png" Width="145" Height="145" Canvas.Top="5" Canvas.Left="380" />
</Canvas>
</Grid>
</Grid>
Not sure what is going wrong here, or if im missing a simple thing like setting the display order for the diffrent canvases
Any Ideas/Advice is appreciated.
Update
I added the entire content panel from my xaml.
heres the function that creates the grid for me when the page is initialized
public void createGrid()
{
//create the grid
Grid backGrid = new Grid();
backGrid.Width = 530;
backGrid.Height = 285;
backGrid.HorizontalAlignment = HorizontalAlignment.Center;
backGrid.VerticalAlignment = VerticalAlignment.Center;
backGrid.ShowGridLines = false;
backGrid.Margin = new Thickness(25, 15, 0, 0);
//define columns
for (int c = 0; c < 10; c++)
{
ColumnDefinition colDef = new ColumnDefinition();
backGrid.ColumnDefinitions.Add(colDef);
}
//define rows
for (int r = 0; r < 6; r++)
{
RowDefinition rowDef = new RowDefinition();
backGrid.RowDefinitions.Add(rowDef);
}
//colour counter
int counter = 0;
//create textboxes
for (int r = 0; r < 6; r++)
{
for (int c = 0; c < 10; c++)
{
//set the coulour of the canvases based on the counter
if (counter == 4)
{
counter = 0;
}
SolidColorBrush tempBrush = new SolidColorBrush();
switch (counter)
{
case 0:
tempBrush = new SolidColorBrush(Colors.Red);
break;
case 1:
tempBrush = new SolidColorBrush(Colors.Orange);
break;
case 2:
tempBrush = new SolidColorBrush(Colors.Blue);
break;
case 3:
tempBrush = new SolidColorBrush(Colors.Green);
break;
}
string canName = c.ToString() + r.ToString();
string txtName = "text" + c.ToString() + r.ToString();
string tempCanName = "canvas" + c.ToString() + r.ToString();
//creating the canvas
Canvas tempCanvas = new Canvas();
tempCanvas.Name = tempCanName;
tempCanvas.Background = tempBrush;
tempCanvas.HorizontalAlignment = HorizontalAlignment.Stretch;
tempCanvas.VerticalAlignment = VerticalAlignment.Stretch;
tempCanvas.Margin = new Thickness(2);
//creating the textblock
TextBlock tempName = new TextBlock();
tempName.Width = 32;
tempName.Height = 32;
tempName.Name = txtName;
tempName.Foreground = new SolidColorBrush(Colors.White);
tempName.TextAlignment = TextAlignment.Center;
tempName.Margin = new Thickness(13, 0, 0, 0);
tempName.FontWeight = FontWeights.Bold;
tempName.HorizontalAlignment = HorizontalAlignment.Center;
tempName.VerticalAlignment = VerticalAlignment.Center;
tempName.Visibility = Visibility.Visible;
tempName.FontSize = 30;
tempName.Tap += tempName_Tap;
//adding the canvas to the grid
Grid.SetRow(tempCanvas, r);
Grid.SetColumn(tempCanvas, c);
//adding all items into the canvas and into the grid
tempCanvas.Children.Add(tempName);
backGrid.Children.Add(tempCanvas);
//increment counter
counter++;
}
}
//add the grid into the mainpage
picCanvas.Children.Add(backGrid);
}
All of this works. I get the grid with all the diffrent colour squares, but when I press textblock, I want my 2nd canvas to pop up and that does not happen. I added breakpoints through out and it goes through all of them, i just dont see the second canvas
heres the code for capturing the tap on the textblock
//function that handels the event when a textblock is tapped
private void tempName_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
//create a copy of the object that triggerd this event
TextBlock tempBlock = sender as TextBlock;
//create a string from the name of this textblock and then cut of the textpart from the name
string tempName = tempBlock.Name;
tempName = tempName.Substring(4);
//move the canvas top or bottom based on which row the current selection is in
string currentRow = tempName.Substring(1);
if ((currentRow == "0") || (currentRow == "1") || (currentRow == "2"))
{
numSelectCan.VerticalAlignment = VerticalAlignment.Top;
}
else
{
numSelectCan.VerticalAlignment = VerticalAlignment.Bottom;
}
//show the number selector control
numSelectCan.Visibility = Visibility.Visible;
}
I am still stuck on this. Cant get numSelectCan to show up...

hello I have tried your code and what i found is that your question is little bit confusing so i assume that you want your second canvas to be visible on tap on the textblock. but you have not register any event-handler on tap on textblock so no event fired that's why first make your textblock visible and add a tap event handler on which you can set the visibility of second canvas.
also tempName_Tap eventHandler is you color gridbox eventhandler not a textblock tap eventhandler so it never register you tap on text block.
Also in the beginning you write that you want your second canvas to be visible on tap on the grid box for that your code is working fine.

I took your xaml/code and tested it out with my own images. Without the images (or entire project) to see how they are drawing on the canvas, I have to say there is a chance that you don't have the correct Z-Index for your 2 canvases. They normally are layered one on top of the other not shifted off to one side. You can set which Canvas is on top of the other by setting the SetZIndex. Try calling:
//show the number selector control
numSelectCan.Visibility = Visibility.Visible;
Canvas.SetZIndex(numSelectCan, 5);
and to hide it again:
//Hide the number selector control
numSelectCan.Visibility = Visibility.Hidden;
Canvas.SetZIndex(numSelectCan, -5);
Of course the Hidden and changing the ZIndex order might be a little redundant. But I have had trouble with one of the canvases taking the events instead of the one that is displayed so I do both.

Related

Add Button to ForEach loop

I have a foreach loop that lists a bunch of websites. I would like the ability to add a button to next to each of these websites.
e.g.
google.com X //X represents button
facebook.com X
I don't think adding a stackpanel is the way to go as I want to add it next to the textblock being created in this for loop.
public void WebsiteList(string[] blocked_sites)
{
Button removewebsite = new Button();
numofsites = blocked_sites.Length;
website.Margin = new Thickness(57, 75, 10, 20);
website.Width = 300;
removewebsite.Width = 20;
removewebsite.Height = 20;
removewebsite.Foreground = Brushes.Red;
removewebsite.Content = "X";
removewebsite.Background = Brushes.Transparent;
website.Foreground = Brushes.White;
website.TextWrapping = TextWrapping.Wrap;
website.FontSize = 13;
foreach (string Site in blocked_sites)
{
website.Inlines.Add(new Run("• "));
string editedSite = Site.Replace("*://*.", "").Replace("*://*", "").Replace("*://", "").Replace("/*", "");
website.Inlines.Add(new Run(editedSite));
website.Inlines.Add(new LineBreak());
removewebsite.Name = "test";
//HERE IS WHERE I WANT TO ADD THE BUTTON ON THE END
}
}
I've tried adding a stackpanel using stackpanel.children.Add(removewebsite) but it's not lining up with the textblocks. I think I'm just lacking sufficient knowledge in the most suitable way to go about it, would love to be pointed in the right direction.
Use an ItemsControl and set or bind its ItemsSource property to the modified string[]:
public void WebsiteList(string[] blocked_sites)
{
numofsites = blocked_sites.Length;
string[] s = new string[numofsites];
for (int i = 0; i < numofsites; ++i)
{
s[i] = string.Format("• {0}{1}", blocked_sites[i].Replace("*://*.", "").Replace("*://*", "").Replace("*://", "").Replace("/*", ""),
Environment.NewLine);
}
ic.ItemsSource = s;
}
XAML:
<ItemsControl x:Name="ic">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding}" Foreground="White" TextWrapping="Wrap" FontSize="13" Margin="57, 75, 10, 20" Width="300" />
<Button Content="X" Foreground="Red" Width="20" Height="30" VerticalAlignment="Center" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

Need to draw rectangles on top of image in FlipView, but FlipView loads 3 images at a time

I have a collection of images i want to show with FlipView. On each image I want to draw multiple rectangles, but to do this I need the current dimensions for the image after it has been rendered. I have the coordinates for the rectangles in the same list as my images. I get the dimensions from the images via ImageOpened event, but the problem is the FlipView event loads three images at the same time causing the different rectangles all to be drawn on the first image. Any suggestions?
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
itemList = e.Parameter as List<TableData>;
foreach (var blobImage in itemList)
{
var request = (HttpWebRequest)WebRequest.Create($"http://localhost:58941/api/image?id={blobImage.ImageBlobName}");
request.Method = "GET";
request.ContentType = "application/json";
WebResponse response = await request.GetResponseAsync();
if (response != null)
{
string responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
var myDict = JsonConvert.DeserializeObject<BlobImage>(responseString);
var jj = new MyImage(blobImage.ImageDescription, myDict.Uri, blobImage.GpsLatitude, blobImage.GpsLongitude, blobImage.GpsAltitude, blobImage.DateTime, blobImage.ObjectsDetected);
MyImages.Add(jj);
}
}
MyFlipView.ItemsSource = MyImages;
}
private void Image_ImageOpened(object sender, RoutedEventArgs e)
{
Image currentImageDimensions = sender as Image;
currentWidth = currentImageDimensions.ActualWidth;
currentHeight = currentImageDimensions.ActualHeight;
foreach (var imageRectangle in itemList)
{
for (int i = 0; i < imageRectangle.ObjectsDetected.Count; i++)
{
rectangle = new Rectangle();
var xMinConvert = Convert.ToDouble(imageRectangle.ObjectsDetected[i].xMin);
var yMinConvert = Convert.ToDouble(imageRectangle.ObjectsDetected[i].yMin);
var xMaxConvert = Convert.ToDouble(imageRectangle.ObjectsDetected[i].xMax);
var yMaxConvert = Convert.ToDouble(imageRectangle.ObjectsDetected[i].yMax);
var xMin = xMinConvert * currentWidth;
var yMin = yMinConvert * currentHeight;
var xMax = xMaxConvert * currentWidth;
var yMax = yMaxConvert * currentHeight;
rectangle.Height = yMax - yMin;
rectangle.Width = xMax - xMin;
var left = ((bgWidth - currentWidth) / 2) + xMin;
var top = ((bgHeight - currentHeight) / 2) + yMin;
rectangle.Margin = new Thickness(left, top, 0, 0);
rectangle.Stroke = new SolidColorBrush(Windows.UI.Colors.Red);
rectangle.StrokeThickness = 1;
layoutRoot.Children.Add(rectangle);
}
}
}
Xaml:
<ScrollViewer DoubleTapped="scrollViewer_DoubleTapped" MinZoomFactor="1" ZoomMode="Enabled" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<Grid x:Name="cGrid" Width="{Binding ElementName=gridbg, Path=ActualWidth}" Height="{Binding ElementName=gridbg, Path=ActualHeight}">
<FlipView SelectionChanged="MyFlipView_SelectionChanged" Name="MyFlipView" Width="{Binding ElementName=gridbg, Path=ActualWidth}" Height="{Binding ElementName=gridbg, Path=ActualHeight}">
<FlipView.ItemTemplate>
<DataTemplate x:DataType="local:MyImage">
<Image Source="{Binding Image}" Stretch="Uniform" Height="{Binding ElementName=gridbg, Path=ActualHeight}" ImageOpened="Image_ImageOpened" />
</DataTemplate>
</FlipView.ItemTemplate>
</FlipView>
</Border>
<Canvas x:Name="layoutRoot">
</Canvas>
</Grid>
</ScrollViewer>
but FlipView loads 3 images at a time
FlipView control supports virtualization at default, load three items at one time is as expected. If disabled the virtualization, all the items will be loaded into the FlipView at one time.
You have several ways to resolve your issue. Since you only need the Rectangle drawing when one FlipViewItem selected, you could put the drawing relative code snippet inside SelectionChanged event handle of FlipView. By doing this you may encounter the issue for getting the Image height and width. Actually you should be able to know the image metadata by getting StorageFile object from uri of the image. If you just want to get the Image control for getting the Height and Width, you may use VisualTreeHelper to get the Image control from FlipView.
Or you could consider to force load only one item to the FlipView each time. For this you could use ISupportIncrementalLoading for incremental loading.
I'm not sure what you are drawing these rectangles for, consider to draw these rectangles to the image before you binding the images to the FlipView if possible.

Highlight text richtextblock UWP

I would like to highlight the text while keeping the same formatting: bold, underline, italic ... But I only managed to highlight the text by losing the formatting. Is it correct to get to what I want or is there an alternative way to highlight the text without having to "split" it and then reassemble it?
xaml:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Width="300">
<RichTextBlock x:Name="RichTextBlockText">
<Paragraph x:Name="Testo">
<Run Foreground="Gray" FontFamily="Segoe UI Light" FontSize="24">
This is a
</Run>
<Run Foreground="Teal" FontFamily="Georgia" FontSize="18" FontStyle="Italic">
different text
</Run>
<Run Foreground="Black" FontFamily="Arial" FontSize="14" FontWeight="Bold">
format
</Run>
</Paragraph>
</RichTextBlock>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Center" Margin="0,25,0,0">
<TextBox x:Name="txbToFind" Height="32" VerticalAlignment="Bottom" Width="200" HorizontalAlignment="Left"/>
<Button x:Name="btnFind" Content="Find" Click="btnFind_Click" HorizontalAlignment="Right" VerticalAlignment="Center"/>
</Grid>
</StackPanel>
</Grid>
xaml.cs:
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void btnFind_Click(object sender, RoutedEventArgs e)
{
string text = string.Empty;
TextBlock NewText = new TextBlock();
string toFind = txbToFind.Text;
for (int a = 0; a <= Testo.Inlines.Count - 1; a++)
{
Run runCorrente = Testo.Inlines[a] as Run;
string currentText;
currentText = runCorrente.Text;
text += currentText;
}
if (text.IndexOf(toFind) >= 0)
{
string[] partOfText = text.Split(new String[] { toFind }, StringSplitOptions.None);
Paragraph paragraph = new Paragraph();
for (int a = 0; a <= partOfText.Length - 1; a++)
{
var piece = partOfText[a];
Run run = new Run();
run.Text = piece;
paragraph.Inlines.Add(run);
if (a < partOfText.Length - 1)
{
MakeHighlightedParagraph(paragraph, toFind, RichTextBlockText);
}
}
RichTextBlockText.Blocks.Clear();
RichTextBlockText.Blocks.Add(paragraph);
}
}
private void MakeHighlightedParagraph(Paragraph paragraph, string textToHighlight, RichTextBlock textBlock)
{
InlineUIContainer cont = new InlineUIContainer();
var border = new Border();
border.MinWidth = textBlock.FontSize / 3.5;
border.Background = new SolidColorBrush(Colors.Yellow);
var text = new TextBlock();
text.Text = textToHighlight;
var margin = textBlock.FontSize * (3.0 / 14.0) + 1.0;
text.Margin = new Thickness(0.0, 0.0, 0.0, -margin);
border.Child = text;
cont.Child = border;
paragraph.Inlines.Add(cont);
}
}
Thanks in advance...!
I have found some possible solutions but I can not use them:
TextRange - that selects a part of text;
TextHighlighter - that highlights one or more text ranges.
But how are they used? Help me please..!
To use TextHighlighters with RichTextBlock, you can first create the desired TextRanges, initialize TextHighlighters using them and then apply them to your RichTextBlock using TextHighlighters property:
TextRange textRange = new TextRange() { StartIndex = 3, Length = 10 };
TextHighlighter highlighter = new TextHighlighter()
{
Background = new SolidColorBrush(Colors.Yellow),
Ranges = { textRange }
};
//add the highlighter
RichBlock.TextHighlighters.Add(highlighter);
There is no a simple property or method being exposed in the RichTextBlock control for your requirement to find the text in the RichTextBlock without losing the formatting, you should set attributes on the every text within the RichTextBlock to make them have the format again. As a simple scenario, you can also just filter the text by a Run object then configure all the text's format.

Select ImageBrush using VisualTreeHelper

I am trying to select ImageBrush items from a LongListSelector. As the ImageBrushes are inside a DataTemplate, I am selecting them using VisualTreeHelper.
My sample xaml code:
<phone:LongListSelector Grid.Row="0" Name="AllPhotosListBox"
SelectionChanged="AllPhotosListBox_SelectionChanged"
ItemsSource="{Binding PhotoItems}"
LayoutMode="Grid" GridCellSize="112, 112">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<Border Margin="24,12,-12,0" Grid.Row="2" BorderThickness="1" BorderBrush="Gray" >
<Grid toolkit:TiltEffect.IsTiltEnabled="True">
<Grid.Background>
<ImageBrush ImageSource="{Binding ImageUrlLow}" Stretch="UniformToFill" />
</Grid.Background>
</Grid>
</Border>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
My sample c# code for selecting ImageBrushes is:
for (int i = 0; i < AllPhotosListBox.ItemsSource.Count; i++)
{
AllPhotosListBox.UpdateLayout();
AllPhotosListBox.ScrollTo(AllPhotosListBox.ItemsSource[i]);
LongListSelector longListBoxItem = AllPhotosListBox as LongListSelector;
longListBoxItem.UpdateLayout();
var grid = VisualTreeHelper.GetChild(longListBoxItem, 0);
var grid1 = VisualTreeHelper.GetChild(grid, 0);
var viewportControl = VisualTreeHelper.GetChild(grid1, 0) as ViewportControl;
var contentPresenter1 = VisualTreeHelper.GetChild(viewportControl, 0) as ContentPresenter;
var canvas1 = VisualTreeHelper.GetChild(contentPresenter1, 0);
var canvas2 = VisualTreeHelper.GetChild(canvas1, 0);
var ContentPresenter2 = VisualTreeHelper.GetChild(canvas2, 0);
var border = VisualTreeHelper.GetChild(ContentPresenter2, 0);
var grid2 = VisualTreeHelper.GetChild(border, 0) as Grid;
ImageSource imgSource = (grid2.Background as ImageBrush).ImageSource;
// doing other stuffs here...
}
But here I am not getting all the imagebrushes. Let, I have ten imagebrushes. But I am getting only two(most of the time the first and the last) imagebrushes which have sources and rest others' sources are empty.
Is there any wrong in my selection. Need help...

How to improve speed of adding controls to UI

I have the following code which creates WPF controls and then adds them to a window in a fashion I need. It works decently, but when trying to create 256 (x4 - two textblocks, combo box, textbox) controls it takes a while to display the tab. Window loads fine but I have many tabs and when I click on point setup tab it lags a little before displaying the tab. It only lags the first time I click on the tab, every time after the first it responds immediately.
At first I thought it was a rendering issue, but after much other research I am of the impression C#/WPF doesn't do well with creating a bunch of objects on the fly and adding them to forms.
If I drop the number of items to 50 it responds immediately, 100 is a slight lag and 200 (256) is a little more of a lag and too much to be acceptable to users.
Any experiences with issues like this before and advice for how to fix it or other tips/tricks.
Thanks in advance!
Wesley
public static void pointSetup(VirtualizingStackPanel desc, VirtualizingStackPanel map) //Draws point description and point map table in point setup tab
{
StackPanel row;
TextBlock text;
TextBox textBox;
ComboBox comboBox;
Thickness rowSpacing = new Thickness(0, 0, 0, 5);
Thickness textSpacing = new Thickness(0, 3, 5, 3);
List<string> list = new List<string>();
list.Add("xx");
for (byte i = 0; i < Global.currentZonesToMap; i++)
{
list.Add("Zone " + (i + 1));
}
for (short i = 0; i < 256; i++)
{
//desc
row = new StackPanel();
row.Margin = rowSpacing;
row.Orientation = Orientation.Horizontal;
text = new TextBlock();
text.Text = "Point " + (i + 1);
text.Margin = textSpacing;
text.Width = 50;
textBox = new TextBox();
textBox.MaxLength = 28;
textBox.Text = "";
textBox.Width = 270;
row.Children.Add(text);
row.Children.Add(textBox);
desc.Children.Add(row);
//map
row = new StackPanel();
row.Margin = rowSpacing;
row.Orientation = Orientation.Horizontal;
text = new TextBlock();
text.Text = "Point " + (i + 1);
text.Margin = textSpacing;
text.Width = 50;
comboBox = new ComboBox();
comboBox.ItemsSource = list;
comboBox.Width = 270;
row.Children.Add(text);
row.Children.Add(comboBox);
map.Children.Add(row);
}
}
New Code (using DataTemplate and ItemsControl)
public class DevicePoint
{
public string desc { get; set; }
public int zone { get; set; }
public List<string> zones { get; set; }
}
//Initialized all variables and displays UI (constructor)
public Dispatcher()
{
InitializeComponent();
List<string> opts = new List<string>();
opts.Add("xx");
for (byte i = 0; i < Global.currentZonesToMap; i++)
{
opts.Add("Zone " + (i + 1));
}
List<DevicePoint> points = new List<DevicePoint>();
for (short i = 0; i < 256; i++)
points.Add(new DevicePoint() { desc = "Point " + (i + 1), zone = 0, zones = opts });
pointDesc.ItemsSource = points;
pointZoneMap.ItemsSource = points;
... other stuff here ...
}
<StackPanel>
<TextBlock Margin="10" FontWeight="Bold" HorizontalAlignment="Center" Text="Point Descriptions" />
<ScrollViewer Width="360" Margin="30,10,30,10" MaxHeight="405">
<ItemsControl Name="pointDesc" Margin="5">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel VirtualizingStackPanel.IsVirtualizing="True" Margin="0,0,0,5" Orientation="Horizontal">
<TextBlock Margin="0,3,5,3" Width="50" Text="{Binding desc}" />
<TextBox MaxLength="28" Width="270" Text="{Binding desc}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</StackPanel>
<StackPanel Grid.Column="1">
<TextBlock Margin="10" FontWeight="Bold" HorizontalAlignment="Center" Text="Point - Zone Map" />
<ScrollViewer Width="360" Margin="30,10,30,10" MaxHeight="405">
<ItemsControl Name="pointZoneMap" Margin="5">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel VirtualizingStackPanel.IsVirtualizing="True" Margin="0,0,0,5" Orientation="Horizontal">
<TextBlock Margin="0,3,5,3" Width="50" Text="{Binding desc}" />
<ComboBox Width="270" ItemsSource="{Binding zones}" SelectedIndex="{Binding zone}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</StackPanel>
If your computer have multiple cores, and I am assuming it have, try to perform the for loop in parallel (parallelfor (from .net 4 or above).
You can set the points List size during creation to 256, this will prevent memory allocations during the items adding operation.
Consider use a StringBuilder if Global.currentZonesToMap is large.
Use StringBuilder to build the value for the DevicePoint.desc string property.
Good luck,
M. Moshe

Categories

Resources