I am working on a silverlight ticker application, something like 5 links will be visible and they will be moving like a ticker(right to left).
I am able to parse the i/p xml file and also getting the Title and corresponding urls, those are coming properly in the page, also its moving like a ticker , but the circular effect is missing.means the continuous flow of links are not proper.
<Grid x:Name="LayoutRoot">
<StackPanel x:Name="mystackpanel" Grid.Column="1" Orientation="Vertical">
<Canvas>
<Canvas.Resources>
<Storyboard x:Name="sb">
<DoubleAnimation x:Name="da" BeginTime="00:00:05"
Storyboard.TargetName="LinkList"
Storyboard.TargetProperty="(Canvas.Left)"
From="0" To="-500" Duration="0:0:5" RepeatBehavior="Forever"/>
</Storyboard>
</Canvas.Resources>
<ListBox x:Name="LinkList"
BorderThickness="0"
Opacity="0.5"
HorizontalAlignment="Left"
>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel x:Name="panel" Orientation="Horizontal" HorizontalAlignment="Left"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<HyperlinkButton x:Name="mylink"
Foreground="Black"
FontSize="10"
FontWeight="Bold"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
Tag="{Binding}"
Content="{Binding Path=Title}"
NavigateUri="{Binding Path=URi}"
IsTabStop="False"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Canvas>
</StackPanel>
</Grid>
How to get the circular effect?
Here is the the simplest approach to get the effect you need.
Set the From in the double animation to the width of the outer StackPanel. That way your URLs start from the extreme right.
Make sure the To value is the negative of at least the full width of the content to be scrolled.
Add a RectangleGeometry to your outer StackPanel that starts at 0,0 and has the width and height of your StackPanel.
Adjust the Duration to get a reasonable pixels/second rate (you want a constant speed not appearing to increase in speed as more content is present).
Related
I'm experiencing an odd behavior with WPF.
My goal here is to have an ItemsControl with a vertical line on each item's side going from the top to the bottom of the item. Being that the items may vary in height, I'm binding the Line's Y2 property to the ActualHeight of the StackPanel belonging to the Grid.
Here's the XAML:
<ItemsControl Grid.Row="1" BorderThickness="0" ItemsSource="{Binding ShipmentActivity}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Name="ListBox">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Line Stroke="{StaticResource ButtonOutlineBrush}" X1="8" X2="8" Y1="0"
Y2="{Binding ActualHeight, ElementName=ShipmentActivity}"
StrokeThickness="1" />
<StackPanel Grid.Column="1" Margin=".1" x:Name="ShipmentActivity">
<StackPanel.Resources>
<Style TargetType="TextBlock">
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
</StackPanel.Resources>
<TextBlock Text="{Binding Status}" FontWeight="SemiBold" FontSize="13" />
<TextBlock Text="{Binding Location}" Foreground="Gray"/>
<TextBlock Text="Wed, Sep 13, 2017, 8:29 PM (2 days ago)" Foreground="Gray"/>
</StackPanel>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Running this at first seems perfect. The problem is noticeable once I start to narrow the width of the window, causing the TextBlocks to wrap, and in effect
causing the items to grow in height, and then resizing the window back to its original width (and beyond). Although the TextBlocks are back to its original state (and height), the height of the items remain the same - stuck at its highest point, leaving huge gaps below the text, while the Line's height doesn't shrink. The Line is definitely the one to blame here, because removing the line removes the issue.
What is even stranger yet, is adding a margin to the StackPanel even the slightest (.1) fixes the issue, and the items shrink back to its intended height.
Am I doing something wrong, or is this a bug?
I would use a Border element to decorate the StackPanel, rather than using a Line. Then just set the BorderThickness property of the Border accordingly.
Hence your XAML would be like this:
<ItemsControl ...>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderThickness="1,0,0,0"
BorderBrush="{StaticResource ButtonOutlineBrush}">
<StackPanel ...>
You can use the Padding property of the Border and/or the Margin property of the StackPanel to space-out the two elements.
In XAML I have:
<sdk:TreeView x:Name="navigationTreeView" Grid.Column="0" Grid.Row="1" SelectedItemChanged="TreeView_SelectedItemChanged">
<sdk:TreeView.ItemContainerStyle>
<Style TargetType="sdk:TreeViewItem">
<Setter Property="IsExpanded" Value="True"/>
</Style>
</sdk:TreeView.ItemContainerStyle>
<sdk:TreeView.ItemTemplate>
<sdk:HierarchicalDataTemplate ItemsSource="{Binding Path=Nodes}">
<StackPanel Orientation="Horizontal">
<!--<Image Source="{Binding Path=ImageUri}" />-->
<TextBlock Text="{Binding Path=Title}" ToolTipService.ToolTip="{Binding Path=Title}"/>
</StackPanel>
</sdk:HierarchicalDataTemplate>
</sdk:TreeView.ItemTemplate>
</sdk:TreeView>
In code behind:
this.navigationTreeView.ItemsSource = nodes;
navigationTreeView.ExpandAll();
There are 1000 items as children of one node. If I'm not expanding elements everything is fine. But when I expand that node it's pretty slow (10 sec maybe). What could I do to speed it up?
Silverlight 4, 2010 april toolkit.
Unlike WPF, Silverlight (until Silverlight 4, not sure about 5) does NOT support UI virtualization for hierarchical data, and this is why when you expand the node, the 1000 items which are inside the HierarchicalDataTemplate are not virtualized and take more than 10 seconds to load.
I believe Telerik's RadTreeView has its built-in UI virtualization, but the control is not free.
The best solution I have found so far is from this site. Please note it is still a ListBox solution, however, because it doesn't use HierarchicalDataTemplate, it is fully virtualized and looks exactly like a TreeView. Also by looking at the source code, it is quite easy to implement.
I know it is not the perfect answer for this question but at least give you some alternatives. :)
This is how the TreeView works. It's virtualized by default: it won't create TreeViewItems until they're needed. However, you're expanding the entire tree which forces all items to be created. That's just inherently slow. If you really need this sort of behavior (where all choices are expanded), I'd suggest something else like a ListBox. Anything that is scrolled off the screen won't be created until it's needed (but see this caveat.)
My bad stack panel is not in the right place...
Ok try this instead:
<sdk:TreeView x:Name="navigationTreeView" Grid.Column="0" Grid.Row="1" SelectedItemChanged="TreeView_SelectedItemChanged">
<sdk:TreeView.ItemContainerStyle>
<Style TargetType="sdk:TreeViewItem">
<Setter Property="IsExpanded" Value="True"/>
</Style>
</sdk:TreeView.ItemContainerStyle>
<sdk:TreeView.ItemTemplate>
<sdk:HierarchicalDataTemplate ItemsSource="{Binding Path=Nodes}">
<StackPanel Orientation="Horizontal">
<!--<Image Source="{Binding Path=ImageUri}" />-->
<TextBlock Text="{Binding Path=Title}" ToolTipService.ToolTip="{Binding Path=Title}"/>
</StackPanel>
</sdk:HierarchicalDataTemplate>
</sdk:TreeView.ItemTemplate>
<sdk:TreeView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</sdk:TreeView.ItemsPanel>
</sdk:TreeView>
Adding:
<sdk:TreeView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</sdk:TreeView.ItemsPanel>
Let me know the results :D
try this:
<sdk:TreeView.ItemTemplate>
<sdk:HierarchicalDataTemplate ItemsSource="{Binding Path=Nodes}">
<VirtualizingStackPanel Orientation="Horizontal">
<!--<Image Source="{Binding Path=ImageUri}" />-->
<TextBlock Text="{Binding Path=Title}" ToolTipService.ToolTip="{Binding Path=Title}"/>
</VirtualizingStackPanel>
</sdk:HierarchicalDataTemplate>
</sdk:TreeView.ItemTemplate>
Replace the normal StackPanel with one VirtualizingStackPanel...
I have an ItemsControl which contains some nested containers. I want to add a dropshadow around each element of the main ItemsControl. But instead it is adding it to certain containers that are within the main ItemsControl (creating rows of shadows). I have placed the effect at a number of different levels but it results in no change. I started out with the outermost container of the item within the main ItemsControl and went upward from there.
Here is where I currently have the effect for the drop shadow placed:
<ItemsControl >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<!-- I have tried adding the dropshadow effect within this stackpanel -->
<StackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- Where I define the dropshadow -->
<ItemsControl.Effect>
<DropShadowEffect BlurRadius="0" ShadowDepth="1" Color="LightGray"/>
</ItemsControl.Effect>
<!-- End of dropshadow definition -->
<ItemsControl.ItemTemplate>
<DataTemplate>
<media:Step5Item />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
And here is the definition for Step5Item, I added documentation for where the shadows are appearing: (edit) I removed the content for the elements since that was just styling and so forth.
<!-- This is inserted by the above code's DataTemplate -->
<!-- I have tried adding a border here and giving it a dropshadow effect -->
<Grid >
<!-- I have tried inserting a dropshadow effect here -->
<TextBlock Grid.Row="0"/>
<Border BorderBrush="LightGray" BorderThickness="1" >
<!-- I have tried inserting a dropshadow effect here -->
<Grid>
<Border >
<!-- There is a shadow around this border/grid -->
<Grid Grid.Row="0" >
<TextBlock Grid.Column="0" />
<Button Grid.Column="2"/>
</Grid>
</Border>
<!--There is a shadow around each element in this ItemsControl-->
<ItemsControl Grid.Row="2" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="0,0,0,4" >
<Path Grid.Row="0">
<Path.Data>
<LineGeometry StartPoint="0,0" EndPoint="1500,0"/>
</Path.Data>
</Path>
<Grid Grid.Row="1">
<Image Grid.Column="0" />
</Grid>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Border>
</Grid>
There is also a shadow at the bottom but I don't know if its from the last element in the ItemsControl or if it is from the outer most border.
If you'd like I can clean up the second code piece more. I took out some stuff but left in the elements, thinking that might be best for readability.
EDIT
I tried applying the effect after I add the child elements hoping that since they would be created before the effect went into play that the problem would not occur. I tried placing the effect at the bottom of both the main ItemsControl as well as at the bottom of the outermost grid in Step5Item. I have also removed some content from Step5Item to make it hopefully more readable.
EDIT2
Here are two images with and without the effect. I left the DropShadow code exactly where I placed it above, though like I said, I can place it in many places to get the same effect.
With Dropshadow
Without Dropshadow
Without Error http://img402.imageshack.us/img402/1456/nodropshadowexample.png
Edit 3
This is the border and drop shadow effect that I am using from Erno's solution. I am hoping to be able to increase the shadowdepth some more because the right side is not getting any shadow, only the bottom. Currently if I change ShadowDepth it changes to location of the shadow to be at a distance away equal to the new size but it is only a thickness of 1.
<Border Margin="0,1,0,0" Height="auto" Width="auto" CornerRadius="5,5,5,5" BorderThickness="1" BorderBrush="LightGray">
<Border.Effect>
<DropShadowEffect BlurRadius="0" ShadowDepth="1" Direction="315" Color="LightGray"/>
</Border.Effect>
</Border>
Have you tried to do the following?
I added another Grid and added a SIBLING Border with the effect. The grid containing the rows is displayed on top of it but is NOT a child control of the Border.
<ItemsControl Grid.Row="2" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="0,0,0,4" >
<Grid>
<Border>
<Border.Effect>
<DropShadow />
</Border.Effect>
</Border>
<Path Grid.Row="0">
<Path.Data>
<LineGeometry StartPoint="0,0" EndPoint="1500,0"/>
</Path.Data>
</Path>
<Grid Grid.Row="1">
<Image Grid.Column="0" />
</Grid>
</Grid>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
I'd like to create a table on WP7. This is my current approach using a ListBox with a Grid as the data template.
<ListBox x:Name="ResultsList" Margin="12,0" Grid.Row="1">
<ListBox.Resources>
<DataTemplate x:Key="ResultsListItem">
<Grid d:DesignWidth="385" Height="28">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="88"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="textBlock1" Margin="0,0,24,0"/>
<TextBlock x:Name="textBlock2" Margin="0,0,24,0"
VerticalAlignment="Top" Grid.Column="1"/>
<TextBlock x:Name="textBlock3" Margin="0,0,24,0"
VerticalAlignment="Top" Grid.Column="3"/>
</Grid>
</DataTemplate>
</ListBox.Resources>
<ListBox.ItemTemplate>
<StaticResource ResourceKey="ResultsListItem"/>
</ListBox.ItemTemplate>
</ListBox>
The problem is, that the resulting table's columns are not sized equally. The Grid's column definitions are applied to each row independently of the other rows. That means, if there is a long text in textBlock1, column 0 will be larger. In the next row there could be a shorter text in textBlock1, resulting in column 0 also being shorter than the column 0 in the previous row.
How can the columns in all rows be sized equally? I don't want to use fixed width because when the orientation changes from portrait to landscape the colums would resize automatically.
There is the HeaderedItemsControl, but as I understand it it is not available for Windows Phone 7?
This is a tricky problem! In WPF there exists the concept of a SharedSizeGroup, which allows you to share column widths across multiple grids, but this is not available in silverlight.
There are a few workarounds on the web:
http://www.scottlogic.co.uk/blog/colin/2010/11/using-a-grid-as-the-panel-for-an-itemscontrol/
http://databaseconsultinggroup.com/blog/2009/05/simulating_sharedsizegroup_in.html
Although neither are simple solutions.
You might also try Mike's AutoGrid:
http://whydoidoit.com/2010/10/06/automatic-grid-layout-for-silverlight/
Here is my solution using SharedSizeGroup as suggested by ColinE.
<ListBox x:Name="ResultsList">
<ListBox.Resources>
<SharedSize:SharedSizeGroup x:Key="Col1Width" />
<SharedSize:SharedSizeGroup x:Key="Col2Width" />
<SharedSize:SharedSizeGroup x:Key="Col3Width" />
<DataTemplate x:Key="ResultsListItem">
<StackPanel d:DesignWidth="385" Orientation="Horizontal">
<SharedSize:SharedSizePanel WidthGroup="{StaticResource Col1Width}">
<TextBlock x:Name="textBlock" MaxWidth="100" Text="{Binding A}"/>
</SharedSize:SharedSizePanel>
<SharedSize:SharedSizePanel WidthGroup="{StaticResource Col2Width}">
<TextBlock x:Name="textBlock1" MaxWidth="85" Text="{Binding B}"/>
</SharedSize:SharedSizePanel>
<SharedSize:SharedSizePanel WidthGroup="{StaticResource Col3Width}">
<TextBlock x:Name="textBlock2" MaxWidth="200" Text="{Binding C}"/>
</SharedSize:SharedSizePanel>
</StackPanel>
</DataTemplate>
</ListBox.Resources>
<ListBox.ItemTemplate>
<StaticResource ResourceKey="ResultsListItem"/>
</ListBox.ItemTemplate>
</ListBox>
Even the maximum with of each column can be controlled via the TextBlock's MaxWidth property. The SharedSizeGroups ensure that the TextBlocks have the same size in each row.
You can use WrapPanel. Set the following ItemsPanel in the Datatemple, you can just have textblock.
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<control:WrapPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
I have a ListBox with a StackPanel that contains an image and label.
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal" IsItemsHost="True" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<Image Source="{Binding Image}" Cursor="Hand" Tag="{Binding Link}" MouseLeftButtonDown="Image_MouseLeftButtonDown" ToolTip="Click to see this product on adidas.com" VerticalAlignment="Top" HorizontalAlignment="Left" />
<Label Content="{Binding Name}" Cursor="Hand" Tag="{Binding Link}" MouseLeftButtonDown="Label_MouseLeftButtonDown" VerticalAlignment="Bottom" Foreground="White" Style="{StaticResource Gotham-Medium}" FontSize="8pt" HorizontalAlignment="Center" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
I want to show a third image (glow.png) behind the currently moused over image. I can't seem to add a second image to the stack panel, and set it's visibility to hidden. I haven't even tackled the mouseover part yet.
Is adding another image inside the stack panel, and then setting it's visibility to visible the right approach on mouseenter, and then swapping back on mouseleave?
Thanks.
You certainly can have one image behind another. Instead of directly adding the image to your StackPanel, add a Grid and then add both images, like this:
<StackPanel Orientation="Vertical">
<Grid>
<Image Source="..." />
<Image Source="{Binding Image}" ... />
</Grid>
<Label Content="{Binding Name}" ... />
</StackPanel>
You might also like to look into Bitmap Effects, using which you can introduce a "glow" effect onto any WPF element.
Edit: Another way to achieve the effect you want (I believe) is to swap out the image's Source property in a trigger. I'm not going to try to write the XAML from memory here, but you could catch the IsMouseOver property for the image itself, and when it switches to True you could set its Source to the "glowing" version of the image.
Another possibility is to add a border to your image, set the color of the borderbrush to whatever you want and the opacity to 0. In your MouseEnter event handler set the opacity to 1.