I have an image in WPF that I would like to have display different information based upon where the mouse is currently hovering. I know I've seen this in websites, I just can't seem to figure out the code to do it in WPF.
The image I'm using is a US map, and I need state specific info to appear as the user crosses the borders. Right now the implementation I'm using is a series of Paths drawn in transparent on top of the map, and then using the Mouse.MouseEnter event to trigger the change. The problem is that the updating seems to suffer from horrible lag, or else the MouseEnter event isn't always catching properly.
Does anybody know of a better way to do this?
Sample C#
private void wyoming_MouseEnter(object sender, MouseEventArgs e)
{
//stateName.Text = "Wyoming";
}
Sample XAML
<Canvas MouseDown="Canvas_MouseDown" Name="canvas">
<Viewbox Stretch="Uniform">
<Image Source="USA.png" />
</Viewbox>
<Path Name="wyoming" Stroke="Transparent" StrokeThickness="1" Mouse.MouseEnter="wyoming_MouseEnter" Mouse.MouseMove="wyoming_MouseMove">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure IsClosed="True" StartPoint="184,121" > <!--NW-->
<PathFigure.Segments>
<PathSegmentCollection>
<LineSegment Point="266,129" />
<LineSegment Point="264,193" />
<LineSegment Point="203,190" />
<LineSegment Point="177,186" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
</Canvas>
Well, after playing around with this more, I discovered my problem was that I had not filled the paths, only kept them as lines. This basically made for a very small event trigger area, and as such WPF sometimes missed the event. By filling them with Transparent, everything works quickly.
Personally what I did for this same instance (except I was labeling info pertaining to time zones and broadcast areas) was I made transparent path shapes for the areas I want able to be activated on mouseover and laid them over a U.S. Map, then I attached an Event trigger to each for the MouseEnter/MouseLeave events so when the user would mouse over the area of whatever Path, it would fire off that condition and do the action specified....in my instance it was showing radio station broadcast times and programs based on region and time zone. So if an are was Moused over, an info box visibility was set to Visible. On MouseLeave that same info box was set to Collapsed....etc
It was very effective and worked real well and you can make your interactive areas very defined when using the precise shapes you made with your Paths. If I can dig up the source I'll try and share but the project was over a year ago so hopefully the description gives you enough of an idea to get the creativity going. :)
Related
I'm trying to draw a round bracket in WPF. I'm working a Math Editor, so I'll need the bracket to be able to stretch in height as required.
Since most of my stretch text research have failed I've decided to get this accomplished by drawing an arcsegement within my user control, And update it's height each time the UserControl changes in height.
But then there's just one problem, I need each part of my bracket to be in the right thickness (I'm a little bit of a perfectionist). Like a perfect bracket.
Notice some parts of the bracket are thicker than others (especially the middle), Is there a way something like that can be accomplished using arcsegment or do I have to put a normal bracket in a Viewbox, stretch it and experiment till I'm satisfied (rather not though).
Any tips/ideas would be awesome:)
Use 2 ArcSegment to form a PathFigure. Here is a tutorial of combining Arc segments.
<Path Stroke="Black" Fill="Black">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigure StartPoint="100,30" IsClosed="True">
<ArcSegment Point="100,130" Size="150 150" />
<ArcSegment Point="100,30" Size="100 100" SweepDirection="Clockwise" />
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
I'd like to create a neon(-like) effect in wpf/c#, to be used on a series of polylines.
The closest i come to this was using blur (not very close, but eh), but the it dims the colors too dark and I have no idea how to make even that glow. Is there an effect close to this, or I should try to write a shader for it somehow?
I'd like to do this for a school project and i'd rather not turn in a bunch of outside libraries for a small amount of self-written code. Also about google: most of the stuff i found were pretty much using blur/dropshadow to create these fading colors, not something that actually has this neon-y effect.
As others have already suggested you should use DropShadowEffect to achieve a neon-like effect:
<Canvas Height="120" Width="280" Background="Black">
<Polyline
Points="10,110 60,10 110,110 105,110 60,18 15,110 10,110"
Stroke="#BB0000"
Fill="#FF0000"
StrokeThickness="2" >
<Polyline.Effect>
<DropShadowEffect Color="#FF9999" ShadowDepth="0" Direction="0" BlurRadius="25" />
</Polyline.Effect>
</Polyline>
<Polyline
Points="10,105 110,105 110,10 115,10 115,110 10,110 10,105"
Stroke="#00BB00"
Fill="#00FF00"
StrokeThickness="2"
Canvas.Left="150">
<Polyline.Effect>
<DropShadowEffect Color="#99FF99" ShadowDepth="0" Direction="0" BlurRadius="25" />
</Polyline.Effect>
</Polyline>
</Canvas>
Unfortunately there is no built-in effect which is specifically designed to create neon effect, but by tweaking the colors you can create quite good (or at least acceptable) results (especially for a school project...):
i use a rectangle lying over other controls to darken them. now, i still want to be able to interact with the controls behind the rectangle, this rectangle will never have another sense than his visual aspect. the problem is, that it catches all clicks & so on, so it's ATM a obstacle.
xaml
<Rectangle Canvas.ZIndex="1" Opacity="0" Name="shadow" Fill="Black"/>
c#
shadow.Opacity = Math.Round(1-(double)(App.Current as App).dimfactor / 255,2);
(App.Current as App).dimfactor is a value between 150 & 255.
how to deal with that?
thanks
I'm not entirely sure if it's the same in WP7 as silverlight but can't you set the IsHitTestVisible bool to false?
<Rectangle Canvas.ZIndex="1" IsHitTestVisible="false" Opacity="0" Name="shadow" Fill="Black"/>
I'm trying to integrate a screenshot grabbing feature in my WPF app and I'd like it to look like snipping tool.
So far I've managed accomplish something similar by creating a fullscreen window (with a canvas) with opacity set to 0.5 and dark background. When I click somewhere and start dragging, a white rectangle is drawn, generating an effect similar to this.
What I'd like to have is the inner part of that rectangle opening a opacity hole in the background canvas, so that I could see through the selected area - just like snipping tool.
Problem is, being fairly new to .NET, I have no idea how or where to start. Did some research and tests on the OpacityMask field of the screenshot window but got nowhere.
Here's a little vid to show the current effect.
Edit: Also, as bonus question, is there an easy way to grab a screenshot that spans across multiple monitors (virtual screen)? Graphics.CopyFromScreen() only seems to work for 1 screen.
Already fixed this and seems to work for all possible weird virtual desktop layouts:
// Capture screenie (rectangle is the area previously selected
double left = Canvas.GetLeft(this.rectangle);
double top = Canvas.GetTop(this.rectangle);
// Calculate left/top offset regarding to primary screen (where the app runs)
var virtualDisplay = System.Windows.Forms.SystemInformation.VirtualScreen;
var primaryScreen = System.Windows.Forms.Screen.PrimaryScreen.Bounds;
if (virtualDisplay.Left < primaryScreen.Left)
{
left -= Math.Abs(virtualDisplay.Left - primaryScreen.Left);
}
if (virtualDisplay.Top < primaryScreen.Top)
{
top -= Math.Abs(virtualDisplay.Top - primaryScreen.Top);
}
You can have a CombinedGeometry with GeometryCombineMode="Exclude" creating a "punched" effect. Sample:
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" AllowsTransparency="True"
WindowStyle="None" Background="Transparent">
<Canvas >
<Path Stroke="Black" Fill="White" Opacity=".5">
<Path.Data>
<CombinedGeometry GeometryCombineMode="Exclude">
<CombinedGeometry.Geometry1>
<RectangleGeometry Rect="0,0,800,600" >
</RectangleGeometry>
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<RectangleGeometry Rect="50,50,100,100" >
</RectangleGeometry>
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</Path.Data>
</Path>
</Canvas>
</Window>
Have a strange one. I have two ellipses that have an opacity of 0.7. What I'd like to do, is where the two ellipses cross, show a different color. In an old WF image I'd have run through each pixel and swapped colours, but I'm not sure how to do this with a layer in Silverlight. Anyone have any ideas?
Thanks!
edit: Sorry, there were a few errors with the properties of the various elements. This is tested:
Create a Path and put as Path.Data a GeometryGroup that has the two EllipseGeometries as child elements. Set GeometryGroup.FillRule to "EvenOdd" so that the area that both ellipses cover is not filled, and set "Fill" to the color you want the ellipses to have (here: AliceBlue).
Put that Path into a Control with "Background" property, like Border, and set that Background to the color you want the area both ellipses are covering to be (here: yellow).
Then you set Clip to the same GeometryGroup with FillRule set to "Nonzero" to prevent the area around the ellipses to also be painted with the background color.
<Border Background="Yellow">
<Path Fill="AliceBlue" Stroke="Black" StrokeThickness="4">
<Path.Data>
<GeometryGroup FillRule="EvenOdd">
<EllipseGeometry Center="100,100" RadiusX="40" RadiusY="80" />
<EllipseGeometry Center="100,100" RadiusX="80" RadiusY="40" />
</GeometryGroup>
</Path.Data>
</Path>
<Border.Clip>
<GeometryGroup FillRule="Nonzero">
<EllipseGeometry Center="100,100" RadiusX="40" RadiusY="80" />
<EllipseGeometry Center="100,100" RadiusX="80" RadiusY="40" />
</GeometryGroup>
</Border.Clip>
</Border>
If you need both ellipses to be painted in different colors use two Border and Path objects, use the same GeometryGroup with "EvenOdd" and set each of Border.Clip to one EllipseGeometry object.
If you need a more detailed definition use a PathGeometry instead of GeometryGroup and define the area with ArcSegments.