Link multiple border/textblock combinations to one event C# - c#

I'm working on a project and have a question to optimize my C# code.
I have 30 rows and 15 columns, the first column contains keywords and the next 14 columns to the left contain all kind of calculations for that keyword.
Now I need to be able to click on a keyword so every calculation form that row is highlighted in another color, and only that row.
My buttons are build with a xaml border + textbox combination and look like this:
<Border x:Name="x_1" Grid.Row="1" Grid.Column="0" Cursor="Hand" MouseLeftButtonUp="btn_1">
<TextBlock FontWeight="Bold" Foreground="Ivory" HorizontalAlignment="Center"
VerticalAlignment="Center">beloof</TextBlock>
</Border>
<Border x:Name="x_2" Grid.Row="2" Grid.Column="0" Cursor="Hand"
MouseLeftButtonUp="btn_2">
<TextBlock FontWeight="Bold" Foreground="Ivory" HorizontalAlignment="Center"
VerticalAlignment="Center">televisie</TextBlock>
</Border>
These are 2 examples of the calculations in xaml code, I read them out of the xml file with xpath and they are build that their x:Name is "number" + row_column.
<TextBlock x:Name="number1_1" Visibility="Visible" Grid.Row="1" Grid.Column="1"
FontWeight="Bold"
Foreground="Ivory"
HorizontalAlignment="Center"
VerticalAlignment="Center">4332.84</TextBlock>
<TextBlock x:Name="number1_2" Visibility="Visible" Grid.Row="1" Grid.Column="2"
FontWeight="Bold"
Foreground="Ivory"
HorizontalAlignment="Center"
VerticalAlignment="Center">4201.62</TextBlock>
Now i could make 30 events in the code behind, one for every 'button' but then every event is almost the same and I dont think that is the right/propper way to do it.
I read some Stackoverflow articles where people said it was possible to attach more buttons to one event. My plan was to load every Border into a List of Borders at initialize, call this list in the general event and load the Borders that have the same row as the Textblocks of the calculations.
Is this the right way to do it ore is there a more optimal way to do it?
Regards Gijs

Related

Layout cycle detected error with two progressRings

I want to create a custom user control with two grids in which I want to load images and until images are loaded I want to show the progressRing control. The problem occurs when I add a second ProgressRing. My XAML looks like this:
<Grid Margin="0,0,0,21" Background="{ThemeResource PhoneAccentBrush}">
<Grid x:Name="leftImage" Margin="10" Width="190" Height="190"
HorizontalAlignment="Left">
<Image x:Name="imageHolderLeft" x:FieldModifier="public" Width="180"
Height="180" ImageFailed="imageHolderLeft_ImageFailed"
ImageOpened="imageHolderLeft_ImageOpened"/>
<Grid>
<ProgressRing x:Name="waitImageLeft" IsActive="True"
VerticalAlignment="Center" HorizontalAlignment="Center"
Background="Transparent"
Foreground="{ThemeResource AppBarBackgroundThemeBrush}"/>
</Grid>
</Grid>
<Grid x:Name="rightImage" Margin="10" Width="190" Height="190"
HorizontalAlignment="Right">
<Image x:Name="imageHolderRight" x:FieldModifier="public" Width="180"
Height="180" ImageOpened="imageHolderRight_ImageOpened"
ImageFailed="imageHolderRight_ImageFailed"/>
<Grid>
<ProgressRing x:Name="waitImageRight" IsActive="True"
VerticalAlignment="Center" HorizontalAlignment="Center"
Background="Transparent"
Foreground="{ThemeResource AppBarBackgroundThemeBrush}"/>
</Grid>
</Grid>
</Grid>
So when I comment out one ProgressRing it works fine, but when there are two of them my program crashes with the following error: Layout cycle detected. Layout could not complete
Does anyone knows why?
Thanks :)
This error indicates that the layout of an element depends on other elements that indirectly depend on the original element. Windows was not able to figure out the overall layout... Much like an infinite loop or infinite recursion.
In your case the cause probably relates to the alignments and sizes. You should be able to solve the problem by simplifying the layout. Keep the outer Grid but add 5 ColumnDefinitions, the middle one having width * and the other ones width Auto. Get rid of the other 4 Grids. Instead, put the two images and progress rings directly into the main Grid in columns number 0, 1, 3, and 4 (using the Grid.Column attached property). Put the desired sizes on the Width and Height properties of the images and progress rings, not on the Grid.

'Live' Slider value into label

I've made an app that allowes me to control a Microsoft NXT 2.0 Mindstorms robot and I've recently added a slider that I want to use to set the current engine speed instead of having a fixed value, so I need help.
Here I have the XAML of the label and slider that I want to use:
<Slider x:Name="Speed" HorizontalAlignment="Left" Margin="40,58,0,0" VerticalAlignment="Top" Width="30" Orientation="Vertical" Height="187" Maximum="90" Minimum="-90" SmallChange="1" LargeChange="10" IsSnapToTickEnabled="True" TickFrequency="5" TickPlacement="BottomRight" AutoToolTipPlacement="BottomRight" MouseUp="Speed_MouseUp" BorderBrush="#00000000" Background="#00000000" Foreground="#FF858585">
<Label x:Name="Current_Speed" Content="Currently: " HorizontalAlignment="Right" Margin="0,0,478,257" Width="60" Height="29" VerticalAlignment="Bottom" Foreground="Black" />
I want Current_Speed to write Currently: {SliderValue} I want it to write the current value of the slider instantly as I move my slider up or down like you can do with the ToolTip option.
Any ideas?
(Bear in mind, I'm not very skilled, so detailed solutions would be much appreciated)
Thank you in advance :)
It's relatively easy. The "trick" is that you need to use two different Label objects, which you can aggregate together using a StackPanel container.
For the second Label object, just set the Label's Content attribute like this:
Content="{Binding ElementName=Speed, Path=Value}"
The whole thing will look something like this:
<Slider x:Name="Speed"
HorizontalAlignment="Left" VerticalAlignment="Top"
Margin="40,58,0,0"
Width="30" Height="187"
Orientation="Vertical"
Maximum="90" Minimum="-90"
SmallChange="1" LargeChange="10"
IsSnapToTickEnabled="True" TickFrequency="5" TickPlacement="BottomRight"
AutoToolTipPlacement="BottomRight"
MouseUp="Speed_MouseUp"
BorderBrush="#00000000" Background="#00000000" Foreground="#FF858585" />
<StackPanel Orientation="Horizontal" Margin="0,0,0,257" Height="29">
<Label x:Name="Current_Speed_Text"
Content="Currently: "
HorizontalAlignment="Right" VerticalAlignment="Bottom"
Foreground="Black" />
<Label x:Name="Current_Speed"
Content="{Binding ElementName=Speed, Path=Value}"
HorizontalAlignment="Right" VerticalAlignment="Bottom"
Foreground="Black" />
</StackPanel>
Note: I have rearranged the layout a bit to ensure the UI elements are properly visible, and have reformatted the XAML itself to aid in readability.
I will also suggest that you use some other mechanism for controlling layout than setting the Margin values. The Margin attribute is very good for ensuring adequate space between elements, but it's not very good at accommodating flexible layout of elements, as it usually requires hand-modifying the margin values as other element characteristics change (e.g. font size, number of characters in the text, etc.).
Likewise, you should use Width and Height sparingly. They have similar problems.
In other words, if you apply the above suggestion to your XAML and it doesn't seem to work, it's because the Label is currently being laid out in such a way that the extra "speed value" text can't be seen.

Get previous item in grid winrt

<Grid x:Name="gridGeneralProperties" HorizontalAlignment="Left" Height="613" Margin="233,5,0,0" Grid.Row="1" VerticalAlignment="Top" Width="437">
<TextBlock TextWrapping="Wrap" Text="General Properties" FontSize="16" Margin="162,10,18,573"/>
<TextBlock TextWrapping="Wrap" Text="Name" Margin="10,69,298,521" FontSize="14.667"/>
<TextBox TextWrapping="Wrap" Text="{Binding Document.DocumentName}" IsReadOnly="True" Margin="144,59,73,520"/>
<AppBarButton x:Name="appBarButtonEditName" HorizontalAlignment="Left" Label="" Margin="349,39,-12,0" VerticalAlignment="Top" Icon="Edit" Height="75"/>
</Grid>
Is there a way to access the previous in a grid? In this case, if a user clicks on the AppBarButton, I want to make the previous TextBox editable. In all instances of where the button is clicked, the previous item will be a TextBox.
In your case - you know which one is previous in your XAML - you can simply name it to access it.
The general solution would be to get the index of the starting element in the Grid.Children collection and the previous one will be at index - 1.
MVVM is the way to go though. I'm also not sure why you would need a button to make a TextBox editable - just leave it editable always and you save the space.

Create control instance in WPF

I want to load multiple images inside a wrappanel, for each image I show a thumbnail and some image details with this code
<Border BorderThickness="1" BorderBrush="#FFD0D1D7" Padding="5" Margin="10,10,0,0">
<StackPanel Orientation="Horizontal">
<!--image and dimensions-->
<Grid Width="88" Height="55">
<Image Source="C:\img1.jpg" Width="88" Height="55"/>
<TextBlock Background="#B2000000" Foreground="White" Height="16" TextAlignment="Center" VerticalAlignment="Bottom">1280x1024</TextBlock>
</Grid>
<!--name, type and size-->
<StackPanel Orientation="Vertical" Margin="5,0,0,0" VerticalAlignment="Center">
<TextBlock Margin="1" Foreground="#FF787878">img13.jpg</TextBlock>
<TextBlock Margin="1" Foreground="#FF787878">Type: JPEG</TextBlock>
<TextBlock Margin="1" Foreground="#FF787878">Size: 321 KB</TextBlock>
</StackPanel>
</StackPanel>
</Border>
But the images are loaded at runtime, and I need some way to create instances of the above code to show the image, dimensions, name, type and size
I tried this solution https://stackoverflow.com/a/4991028/962284
StringBuilder sb = new StringBuilder();
// use xaml to declare a button as string containing xaml
sb.Append(#"<Border BorderThickness='1' BorderBrush='#FFD0D1D7' Padding='5' Margin='10,10,0,0'>
<StackPanel Orientation='Horizontal'>
<!--image and dimensions-->
<Grid Width='88' Height='55'>
<Image Source='C:\img1.jpg' Width='88' Height='55'/>
<TextBlock Background='#B2000000' Foreground='White' Height='16' TextAlignment='Center' VerticalAlignment='Bottom'>1280x1024</TextBlock>
</Grid>
<!--name, type and size-->
<StackPanel Orientation='Vertical' Margin='5,0,0,0' VerticalAlignment='Center'>
<TextBlock Margin='1' Foreground='#FF787878'>img13.jpg</TextBlock>
<TextBlock Margin='1' Foreground='#FF787878'>Type: JPEG</TextBlock>
<TextBlock Margin='1' Foreground='#FF787878'>Size: 321 KB</TextBlock>
</StackPanel>
</StackPanel>
</Border>");
FrameworkElement thumb = (FrameworkElement)System.Windows.Markup.XamlReader.Parse(sb.ToString());
ThumbnailContainer.Children.Add(thumb);
but I get the following error
I also tried with styles, but styles doesnt support multiple parameters (to specify the textblocks: dimensions, size, name, type and size) just "TemplateBinding Tag" for 1 value
What can I do to create instances of the first code to show multiple images at runtime?
Wow. That so looks like the hard way to do things. Time to embrace WPF and XAML.
I had a post about this exact same thing that wasn't quite finished. I took time to finish it for you. I even used your XAML snippet (well, a modified version of it) in the example, just for you.
http://www.wpfsharp.com/2012/10/23/displaying-images-from-a-folder-with-details-in-wpf/
Clemens is correct in his comment to use an ItemsControl.
Yes your approach is wrong and you should be doing this some other way but to get your code snippet to work try adding xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" to your Border element in the string you are building. I suspect that is the error.

Scrollable textblock in windows phone 7

I am trying to create a scrollable text block.
But it dont seem to works.
How should i go about doing it?
Below is my code:
<Grid x:Name="ContentGrid" Grid.Row="1">
<ScrollViewer>
<TextBlock Height="517" HorizontalAlignment="Left" Margin="33,16,0,0" Name="textBlockRules" Text="" VerticalAlignment="Top" Width="414" FontSize="25" TextWrapping="Wrap" /></ScrollViewer>
Even though you didn't mention explicitly, I'm guessing that your aim is to show some large text without getting chopped.
For such a requirement there are helpful threads on stackoverflow:
1. Need to show large amount of text on windows phone 7 screen
2. Programmatically determining max fit in textbox (WP7)
On the other hand, if all you want is have text blocks in a sequence, you can use a ListBox that is databound to a list.
You have to set the maximum height of the ScrollViewer and could set the Visibility for the Scrollbars to Auto.
Here is the example from the msdn:
<ScrollViewer Height="200" Width="200" HorizontalScrollBarVisibility="Auto" Canvas.Top="60" Canvas.Left="340">
<TextBlock Width="300" TextWrapping="Wrap"
Text="I am the very model of a modern Major-General, I've information vegetable, animal, and mineral, I know the kings of England, and I quote the fights historical, From Marathon to Waterloo, in order categorical; I'm very well acquainted, too, with matters mathematical, I understand equations, both the simple and quadratical, About binomial theorem I'm teeming with a lot o' news, With many cheerful facts about the square of the hypotenuse." />
</ScrollViewer>
Set scrollviewerHorizontalBar to visibal, make textbok stretch and make sure your text is long enough, something like this:
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Name="Scroller">
<TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MinWidth="100" Width="{Binding ElementName=Scroller, Path=ViewportWidth}"
TextWrapping="Wrap" Text="Some really long text that should probably wordwrap when you resize the window." />
</ScrollViewer>

Categories

Resources