|
|
Thanks a lot. Freezing the Pen did the Trick.
|
|
|
|
|
I have a layout like this
<Canvas x:Name="LayoutRoot"...
<StackPanel...
<Rectangle...
<StackPanel...
<Image...
What I'd like to do is get the Top and Left of the image when the mouse enters it so I can position other elements. I've tried [ImageName].GetValue(Canvas.TopProperty); but it always returns 0.0. What's the trick here?
only two letters away from being an asset
|
|
|
|
|
Hello,
You can use TransformToVisual method.
Example: http://www.cdn.pl/blog/post/2008/09/05/Silverlight-Tip-1-How-to-find-the-absolute-position-of-any-control-.aspx
|
|
|
|
|
Thanks. I just found a similar post.
only two letters away from being an asset
|
|
|
|
|
|
Now where were these 2 years ago? Good resources though.
|
|
|
|
|
Hi all,
i'm a beginner in Wpf as Linq so i need help to understand better some features.
I'm studying on DataGrid now ,i download a demo of Infragistic and Xceed both are good ,my purpose why i study DataGrid because i wish create a database with SqlServer (now i use Northwind database like example)and use Linq as Orm to populate a DataGrid and insert 3 button: Add, Edit,Remove for handle the database so i ask you some advice,information to help me to catch up my goal also if you have a link to show it is very useful.
Thanks for your attention.
I wish you happy day.
Bye
|
|
|
|
|
I'm trying to convert GDI+ project into WPF.
The GDI+ code (see below) interlaces 3 images into one:
Image 1 | Image 2 | Image 3 > Combined Image
-------------------------------------------------
11111 | 22222 | 33333 > 123123123123123
11111 | 22222 | 33333 > 123123123123123
11111 | 22222 | 33333 > 123123123123123
11111 | 22222 | 33333 > 123123123123123
11111 | 22222 | 33333 > 123123123123123
I think that if an Linear Gradent Brush in an Opacity Mask is used on the 3 input Visual Brushes, it should be possible to interlace video in real time - I can figure out the concept but not sure how to get it done. Needs to be pixel perfect masking for a 1080 x 1920 (portrait) display area...
As I'm still a noobie at WPF, is there anyone who can help or guide me?
Thanks in advance...
Graeme
Sample GDI+ code is as follows:
Imports System.Math
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Drawing.Imaging
Imports System.Drawing.Text
Public Class Form1
#Const DEBUG = 0
Private Filter As Region
Dim Images(5) As TextureBrush
Private ndx As Integer = 0
Dim Toggle As Integer = 0
#If Debug = 1 Then
Dim cnt As Integer
#End If
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Images(0) = New TextureBrush(My.Resources.Image1)
Images(1) = New TextureBrush(My.Resources.Image2)
Images(2) = New TextureBrush(My.Resources.Image3)
Images(3) = New TextureBrush(My.Resources.Image4)
Images(4) = New TextureBrush(My.Resources.Image5)
Images(5) = New TextureBrush(My.Resources.Image6)
' Prep a Stripped-View Filter.
Filter = New Region(New Rectangle(0, 0, 1930, 1080))
Using pa As New GraphicsPath()
For iTop As Integer = 0 To Me.Height Step 3
pa.AddRectangle(New Rectangle(0, iTop, 1930, 2))
Next
Filter.Exclude(pa)
End Using
End Sub
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
' Draw Base image
e.Graphics.FillRectangle(Images(GetPtr(0)), New Rectangle(0, 0, 1920, 1080))
' Draw interlaced images
For i = 1 To 2
e.Graphics.TranslateTransform(0, i)
e.Graphics.FillRegion(Images(GetPtr(i)), Filter)
'e.Graphics.FillRegion(Images(GetPtr(0)), Filter)
Next
' Toggle Logo Postion - From middle to sides and back
Toggle = Toggle Xor 1
' Pass painting back to caller
MyBase.OnPaint(e)
' Reposition count so that each AD image appears RHS > Middle > LHS
If Toggle Then PrevNdx() Else NextNdx()
End Sub
Private Function NextNdx() As Integer
ndx += 1
If ndx > Images.Length - 1 Then ndx = 1
Return ndx
End Function
Private Function PrevNdx() As Integer
ndx -= 1
If ndx < 1 Then ndx = Images.Length - 1
Return ndx
End Function
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Me.Invalidate()
End Sub
End Class
modified on Sunday, November 16, 2008 8:26 AM
|
|
|
|
|
You can get close to what you need using an ImageBrush as the OpacityMask. In the example a 3px wide image is used and tiled and offset.
<Window x:Class="Interlace.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="771" Width="741">
<Grid SnapsToDevicePixels="True">
<Rectangle Width="600" Height="400" Fill="Red" x:Name="r"/>
<Rectangle Width="600" Height="400" Fill="Green" x:Name="g"/>
<Rectangle Width="600" Height="400" Fill="Blue" x:Name="b" />
</Grid>
</Window>
private BitmapSource CreateMask(int size)
{
WriteableBitmap bmp = new WriteableBitmap(size, 1, 96, 96, PixelFormats.Pbgra32, null);
int[] mask = new int[size];
int opaque = BitConverter.ToInt32(new byte[] { 255, 255, 255, 255 }, 0), transparent = BitConverter.ToInt32(new byte[] { 255, 255, 255, 0 }, 0);
mask[0] = opaque;
for (int i = 1; i < mask.Length; i++)
mask[i] = transparent;
bmp.WritePixels(new Int32Rect(0, 0, size, 1), mask, size * 4, 0);
return bmp;
}
var mask = CreateMask(3);
RenderOptions.SetBitmapScalingMode(g, BitmapScalingMode.NearestNeighbor);
RenderOptions.SetBitmapScalingMode(b, BitmapScalingMode.NearestNeighbor);
b.OpacityMask = new ImageBrush(mask) {TileMode = TileMode.Tile, Viewport = new Rect(0,0,1.0/200,1)};
g.OpacityMask = new ImageBrush(mask) {TileMode = TileMode.Tile, Viewport = new Rect(1.0/600, 0, 1.0 / 200, 1) };
If you zoom in you should see red green and blue 1px stripes, try print-scrn.
If your using video I don't know what to expect, you say you want it pixel perfect but I would be suprised if you could handle 3 HD videos at the same time. I think nearest neighbor interpolation only got added in .NET 3.5 sp1 because of that dependency you might want to try a pixel shader instead, I had some success trying that.
Why can't you do the processing offline and just use a single video?
|
|
|
|
|
Hi Insincere Dave,
Thanks for attempting this problem. I haven't had a change to try what you suggest but it looks good - will try tonight...
What I'm using this for is to write a prototype demo for a new 'TripleView' screen that we've been given a chance to test. The screen allows 3 images to be displayed at 3 different angle simultaneously. So 3 people a 3 different locations see different content simultaneously. Pretty cool huh? Imagine if it included TV tuners... The possibilities...
So, I can render static images easily. I trust that yours does the same. Maybe I need to do something with the Visualbrush for video...
Anyone else got any thoughts?
Graeme
|
|
|
|
|
If you replace the coloured rectangles with mediaelements you should be able to do it. I don't know about the performance though.
|
|
|
|
|
Insincere Dave wrote: If you replace the coloured rectangles with mediaelements you should be able to do it. I don't know about the performance though.
I've changed your initial sample code to mediaelemets and added video. When run in 1200 x 600 (due to my Notebook PC screen resolution limitation) with a LayoutTransform applied to rotate the video from landscape to portrait, the CPU load when run in the IDE in Debug Mode is 42~47%... I'll load up FHD (1920 x 1080) video in the office tomorrow and will measure the load again... Somehow I don't think it will be a problem.
Revised test XAML used:
<Window x:Class="TestWPF___TripleView.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Width="1200" Height="600"
WindowStyle="None" ResizeMode="NoResize" WindowStartupLocation="CenterScreen" Background="Black">
<Canvas SnapsToDevicePixels="True" Loaded="WindowLoaded">
<MediaElement Width="600" Height="1200"
Source=".\Video\1.mpg"
x:Name="r"
Stretch="Fill">
<MediaElement.LayoutTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<RotateTransform Angle="-90"/>
</TransformGroup>
</MediaElement.LayoutTransform>
</MediaElement>
<MediaElement Width="600" Height="1200"
Source=".\Video\2.wmv"
x:Name="g"
Stretch="Fill">
<MediaElement.LayoutTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<RotateTransform Angle="-90"/>
</TransformGroup>
</MediaElement.LayoutTransform>
</MediaElement>
<MediaElement Width="600" Height="1200"
Source=".\Video\3.mpg"
x:Name="b"
Stretch="Fill">
<MediaElement.LayoutTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<RotateTransform Angle="-90"/>
</TransformGroup>
</MediaElement.LayoutTransform>
</MediaElement>
</Canvas>
</Window>
Mate... You are an absolute legend!
Graeme
modified on Wednesday, November 19, 2008 7:47 AM
|
|
|
|
|
Is there a good way to bind an element created through a DataTemplate to
an attached property?
Please refer to this post[^] for full source code
(scroll down to around the smiley)...
Elements are created through a DataTemplate and end up as children of a Grid.
The data has Row and Col properties that need to be bound to the Grids Row and
Column attached properties.
The most obvious binding (to me) would be something like this:
<DataTemplate DataType="{x:Type local:Obs}">
<Button <code>Grid.Row="{Binding Path=Row}" Grid.Column="{Binding Path=Col}"</code> Click="Button_Click">
<Button.Style>
<Style TargetType="{x:Type Button}" >
<Setter Property="Content" Value="{Binding Path=Name}"/>
<Setter Property="Width" Value="50"/>
<Setter Property="Height" Value="Auto"/>
<Setter Property="Margin" Value="2"/>
<Setter Property="Background" Value="#FFBBBB00"/>
<Setter Property="Foreground" Value="#FF000000"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Status}" Value="On">
<Setter Property="Background" Value="#FFFFFF00"/>
<Setter Property="Foreground" Value="#FFFF0000"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</DataTemplate>
but it doesn't work, I assume because the element isn't yet a child
of the grid at the time the binding is created.
Based on that assumption, I figured I needed an event of some kind to give me a chance to
do the binding once the created element is a child of the grid.
As seen in the code, my workaround was to override ArrangeOverride() on the Grid
and programatically create the binding there. That works, but I hate it
Is there a better way?
I'd love to do it completely in XAML, but I'm not smart enough yet.
Thanks!
Mark
Mark Salsbery
Microsoft MVP - Visual C++
modified on Friday, November 14, 2008 7:23 PM
|
|
|
|
|
Inside a datatemplate you can bind to a relative source, a parent, of the object by using the RelativeSource attribute.
You should try and experiment with something like:
<DataTemplate DataType="{x:Type local:Obs}">
<Button Grid.Row="{Binding Path=Row, RelativeSource={RelativeSource AncestorType={x:Type Grid}}}"
Grid.Column="{Binding Path=Col, RelativeSource={RelativeSource AncestorType={x:Type Grid}}}"
Click="Button_Click">
..
Good Luck!
Dawn is nature's way of telling you to go to bed.
|
|
|
|
|
I've experimented for HOURS on this
Anyway, that doesn't work in the context of the code I linked to
(a DataTemplate for an ItemsControl ItemsTemplate)...tried it already,
and tried it again.
I do appreciate the help, thanks!
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
My fault... I misread your post, I guess I was working a bit too late...
Anyway, I just recreated a solution based on your code in a previous post. I do not entirely understand what you're trying to do... When I click the Test button, button 3 moves to the first column and a 6th button is added to the grid. Like this:Screenshot[^].
Is this what is supposed to happen? If not, could you explain a bit more about what should happen.
Dawn is nature's way of telling you to go to bed.
|
|
|
|
|
Timmy Kokke wrote: Is this what is supposed to happen?
Yes
I was demonstrating to the OP how changing the data would reflect
in the UI - the test showed you can change the cell position of existing
objects in the collection and add items to the collection.
The code I posted works like I wanted it to....I just didn't like the way
I did the binding from the data object's Row and Col properties to the
Grid.Row and Grid.Column attached properties, and I could't figure out
a better way, so I started this new thread.
Cheers,
Mark
Mark Salsbery
Microsoft MVP - Visual C++
modified on Saturday, November 15, 2008 12:51 PM
|
|
|
|
|
The reason why this does not work is because the ItemsControl wraps your object in a container. To get the binding you want you will need to make an StyleSelector to assign to the ItemContainerStyleSelector property of the Items control. Something like this should work:
Public Overrides Function SelectStyle(ByVal item As Object,
ByVal container As System.Windows.DependencyObject)
As System.Windows.Style
Dim matElem As Obs = TryCast(item, Obs)
Dim ret As New Style()
If matElem IsNot Nothing Then
ret.Setters.Add(New Setter(Grid.RowProperty, matElem.PositionY))
ret.Setters.Add(New Setter(Grid.ColumnProperty, matElem.PositionX))
End If
Return ret
End Function
|
|
|
|
|
Excellent Gideon, thank you!
StyleSelector is news to me
I actually needed bindings, not just setters for the initial value, but I'm
much more comfortable setting them in the item style selector than in the
grid ArrangeOverride like I was doing in my hacked solution. This is a much
more appropriate place to set the bindings and I was able to remove the silly
IsBoundToUI flag from the data object class.
Here's what I did:
public class ObsItemStyleSelector : StyleSelector
{
public override Style SelectStyle(object item, DependencyObject container)
{
Obs obs = item as Obs;
ContentPresenter cp = container as ContentPresenter;
if (null != obs && null != cp)
{
Binding binding = new Binding("Row");
binding.Source = obs;
cp.SetBinding(Grid.RowProperty, binding);
binding = new Binding("Col");
binding.Source = obs;
cp.SetBinding(Grid.ColumnProperty, binding);
}
return null;
}
}
That works well!
Thanks again,
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Can someone tell me how to play an swf file via WPF?
Please I need it asap
Thanks
Happy Programming!
Regards,
ctrlnick !
|
|
|
|
|
You need to embed the flash player in your WPF application. You'd use the WindowsFormsHost to put the control in - and you'd have to wrap the ActiveX control.
|
|
|
|
|
I tried, Can you show me sample code?
Happy Programming!
Regards,
ctrlnick !
|
|
|
|
|
|
|