WindowsFormsHost white first time - wpf

I have a WPF window that basically has this occupying its entire space:
<WindowsFormsHost Grid.RowSpan="2" Name="wfh" VerticalAlignment="Stretch" Width="Auto" Height="Auto" Cursor="IBeam" ForceCursor="True" SnapsToDevicePixels="True" >
<ax:AxViewerActiveX x:Name="_axViewer" AutoSize="True" Cursor="Cross" Margin="0,0,0,0" Padding="0,0,0,0" UseWaitCursor="True">
</ax:AxViewerActiveX>
</WindowsFormsHost>
The first time I do ShowDialog() of this window, the window appears blank:
The second time it appears as it should:
Please, can someone help to make the rendering of the window correctly the first time?
Constructor of this window class:
this.InitializeComponent();
_axViewer.BeginInit();
_axViewer.EndInit();
Focus();
_axViewer.Focus();
When calling it is simple as:
w3d.WindowState = WindowState.Maximized;
w3d.ShowDialog();

Try putting the initialization for the ActiveX control in the .Loaded() method?
this.InitializeComponent();
Loaded += delegate {
_axViewer.BeginInit();
_axViewer.EndInit();
Focus();
_axViewer.Focus();
};

Related

Defining CustomMessageBox from Windows Phone Toolkit in XAML

Can I define CustomMessageBox in XAML? I have the code:
<phone:phone:PhoneApplicationPage.Resources>
<toolkit:CustomMessageBox x:Key="CustomMessageBox" Title="Blabla" IsLeftButtonEnabled="True" LeftButtonContent="OK" Content="blabla" />
</phone:PhoneApplicationPage.Resources>
And when I'm trying to run it:
(this.Resources["CustomMessageBox"] as CustomMessageBox).Show();
I get InvalidOperationException - "Element is already the child of another element.".
Is it possible to do it this way or I have to define it from code-behind? Is there any workaround?
Due to this book (not advertizing, just showing source), you can do follow:
1 Create new UserControl, name it CustomUserControl.xaml
2 Add custom UI elements to UC
<StackPanel x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}" Margin="0,0,0,10">
<TextBlock Text="Custom content inside the UserControl XAML" TextWrapping="Wrap"
HorizontalAlignment="Left"/>
<MediaElement Source="http://mschannel9.vo.msecnd.net/o9/mix/09/wmv/key01.wmv"/>
</StackPanel>
3 Run from codebehind of your main page
var messageBox = new CustomMessageBox
{
Content = new CustomUserControl(),
LeftButtonContent = "OK",
RightButtonContent = "Cancel",
};
messageBox.Show();
Seems now you can play video in message box :)
PS: also found some info here

how to capture part of the screen in Silverlight

i want to do a screen capture of a running silverlight 3 application, from within the app, and then i want to present this to the user as a thumbnail, say in an Image control.
am i dreaming?
For a simple page:
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel>
<Ellipse Fill="Red" Width="100" Height="100"></Ellipse>
<Button x:Name="btnCapture" Click="btnCapture_Click" Width="30" Height="25"></Button>
<Image x:Name="imgThumbnail" Width="50" Height="50"></Image>
</StackPanel>
</Grid>
with the event handler:
private void btnCapture_Click(object sender, RoutedEventArgs e)
{
WriteableBitmap bmp = new WriteableBitmap(LayoutRoot, null);
this.imgThumbnail.Source = bmp;
}
You are dreaming if you want to do a true screen capture (outside the plugin).
The WriteableBitmap answer is correct if you just want to capture a partial or complete visual tree rendering of the Silverlight app only.

Silverlight 4 web cam permission on load of User Control

I am using Silverlight 4 to access the web cam. Everything works ok when I start the web cam on a button click event, I get the prompt for permission. I would like the web cam to start when User Control loads, but for some reason when I run the same code on the Loaded event, I don't get a prompt when executing the following code:'
CaptureDeviceConfiguration.RequestDeviceAccess()
Does anyone have a work around for this?
I found a workaround to the problem. I am automatically clicking the button that starts the webcam streaming on the Loaded event of the control.
ButtonAutomationPeer peer = new ButtonAutomationPeer(btnStartWebcam);
IInvokeProvider invokeProv =
peer.GetPattern(PatternInterface.Invoke)
as IInvokeProvider;
invokeProv.Invoke();
This does the job for me because I don't mind having a button on the UI. But I guess you can create a dummy one and hide it if it's necessary.
The security around accessing local devices is very tight. Starting the capture must be preceded by a user action.
Instead of starting the capture from the loaded event, you'll have to move it to a Click event.
Code behind:
public void StartCam()
{
VideoCaptureDevice dev = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
if(CaptureDeviceConfiguration.RequestDeviceAccess() &&
CaptureDeviceConfiguration.AllowedDeviceAccess)
{
CaptureSource capture = new CaptureSource();
capture.VideoCaptureDevice = dev;
VideoBrush videoBrush = new VideoBrush();
videoBrush.SetSource(capture);
capture.Start();
WebCamRectangle.Fill = videoBrush;
}
}
private void button1_Click(object sender, RoutedEventArgs e)
{
StartCam();
}
Xaml:
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="49*" />
<RowDefinition Height="251*" />
</Grid.RowDefinitions>
<Rectangle Name="WebCamRectangle"
Stroke="Black" StrokeThickness="1" Grid.Row="1" />
<Button Content="Start" Height="25" HorizontalAlignment="Left"
Margin="12,12,0,0" Name="button1" VerticalAlignment="Top"
Width="135" Click="button1_Click" />
</Grid>

VisualBrush of a Window in another Window

So basically, the MainWindow opens a second Window, let's say OptionsWindow. So in the OptionsWindow I want to show a visual of the MainWindow. I tried this, but didn't work:
<Rectangle Grid.Row="1" Margin="3" Height="100">
<Rectangle.Fill>
<VisualBrush Visual="{Binding Application.Current.MainWindow}" />
</Rectangle.Fill>
</Rectangle>
Any help greatly appreciated.
EDIT:
I found the obvious answer:
windowPreview.Visual = Application.Current.MainWindow;
The only weird thing is that it calls the Loaded event of the MainWindow again and I have some code there that should only run when the MainWindow first loads. I though it would just show the current instance of the MainWindow. Any workaround on this?
If you put the load code in the constructor for the MainWindow that should only get called once per instance.
I'm not sure if it is a bug that WPF calls the Load event more than once for any given window, but it sounds like it might be by design for cases where a user closes and reloads the window...

Can you override just part of a control template in silverlight

Is it possible to change or modify a specific part of a control template without having to recreate the entire control template of the control in the xaml?
For example, I was trying to get rid of the border of a textbox, so I could throw together a basic search box with rounded corners (example xaml below). Setting the borderthickness to 0 works fine, until you mouse over the textbox and a pseudo border they added to the control flashes up. If I look at the controltemplate for the textbox, I can even see the visual state is named, but cannot think of how to disable it.
Without overriding the control template of the TextBox, how would I stop the Visual State Manager firing the mouse over effect on the TextBox?
<Border Background="White" CornerRadius="10" VerticalAlignment="Center" HorizontalAlignment="Center" BorderThickness="3" BorderBrush="#88000000">
<Grid VerticalAlignment="Center" HorizontalAlignment="Center" Width="200" Margin="5,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="16" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Path Height="13" Width="14" Stretch="Fill" Stroke="#FF000000" StrokeThickness="2" Data="M9.5,5 C9.5,7.4852815 7.4852815,9.5 5,9.5 C2.5147185,9.5 0.5,7.4852815 0.5,5 C0.5,2.5147185 2.5147185,0.5 5,0.5 C7.4852815,0.5 9.5,2.5147185 9.5,5 z M8.5,8.4999971 L13.5,12.499997" />
<TextBox GotFocus="TextBox_GotFocus" Background="Transparent" Grid.Column="1" BorderThickness="0" Text="I am searchtext" Margin="5,0,5,0" HorizontalAlignment="Stretch" />
</Grid>
</Border>
I've found a way to do this, by inheriting off the control and overriding the OnApplyTemplate. It's not ideal, but I think it's better than having to copy the entire control template. Here's an example of creating a borderless textbox, essentially disabling the mouse over visual state by always clearing the storyboard:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;
namespace SilverlightTestApplication
{
public class BorderlessTextBox : TextBox
{
public BorderlessTextBox()
{
BorderThickness = new System.Windows.Thickness(0);
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
//Get the mouse over animation in the control template
var MouseOverVisualState = GetTemplateChild("MouseOver") as VisualState;
if (MouseOverVisualState == null)
return;
//get rid of the storyboard it uses, so the mouse over does nothing
MouseOverVisualState.Storyboard = null;
}
}
}
Its been awhile since I used XAML, but no, I don't believe you can just modify a piece of the template.
However if you have the IDE you can create a copy of the currently applied template and just modify the piece you want and leave the rest as is. See the How to Edit section of this link.
Retrieve the default template of every control, with the XAML reader, then copy/paste and modify what you want... not very clean but I think this is the only way (I'm searching how to retrieve this default template)
In WPF, not sure about silverlight here a snippet of code to retrieve the template of Aero, you can try to copy/paste and change what you want:
public Window1()
{
InitializeComponent();
using(FileStream fs = new FileStream("C:/TextBoxTemplate.xaml", FileMode.Create))
{
var res = LoadThemeDictionary(typeof(TextBox), "Aero", "NormalColor");
var buttonRes = res[typeof(TextBox)];
XamlWriter.Save(buttonRes, fs);
}
}
public static ResourceDictionary LoadThemeDictionary(Type t,
string themeName, string colorScheme)
{
Assembly controlAssembly = t.Assembly;
AssemblyName themeAssemblyName = controlAssembly.GetName();
object[] attrs = controlAssembly.GetCustomAttributes(
typeof(ThemeInfoAttribute), false);
if(attrs.Length > 0)
{
ThemeInfoAttribute ti = (ThemeInfoAttribute)attrs[0];
if(ti.ThemeDictionaryLocation ==
ResourceDictionaryLocation.None)
{
// There are no theme-specific resources.
return null;
}
if(ti.ThemeDictionaryLocation ==
ResourceDictionaryLocation.ExternalAssembly)
{
themeAssemblyName.Name += "." + themeName;
}
}
string relativePackUriForResources = "/" +
themeAssemblyName.FullName +
";component/themes/" +
themeName + "." +
colorScheme + ".xaml";
Uri resourceLocater = new System.Uri(
relativePackUriForResources, System.UriKind.Relative);
return Application.LoadComponent(resourceLocater)
as ResourceDictionary;
}
I 've never used Silverlight, but I don't think there is a lot of things to do to adapt this template to Silverlight.
Source : Default template in WPF

Resources