XAML from file as element - wpf

Hi i want to load my element during program start from external file.
Below is my code:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:FromFile3d" x:Class="FromFile3d.MainWindow"
Title="MainWindow" Height="400" Width="800">
<Grid>
<Grid.Background>
<LinearGradientBrush EndPoint="0.789,0.541" StartPoint="0.225,0.543">
<GradientStop Color="Black" Offset="0.849"/>
<GradientStop Color="#FF232323" Offset="1"/>
</LinearGradientBrush>
</Grid.Background>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="527*"/>
<ColumnDefinition Width="265*"/>
</Grid.ColumnDefinitions>
<Button Content="Button" Grid.Column="1" HorizontalAlignment="Left" Height="26" Margin="161,28,0,0" VerticalAlignment="Top" Width="75"/>
<Viewport3D x:Name="_viewport3D" />
</Grid>
and for last cs with load method
private void LoadCore()
{
string path = System.IO.Path.Combine(Directory.GetCurrentDirectory(), "test.xaml");
if (path != null)
{
try
{
StreamReader mysr = new StreamReader(path);
_viewport3D= XamlReader.Load(mysr.BaseStream) as Viewport3D;
}
catch (Exception e)
{
MessageBox.Show(
String.Format("Unable to parse file:\r\n\r\n{0}",
e.Message), "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
and file that i want to load is Viewport3d definition with my scene and model and ends with /Viewport3D ( i couldn't paste it, don't know why )
What i'm doing wrong ? because nothing happens when program starts my model is invisible :> (it's not the problem with viewport code because it work's fine before moving to external file).

_viewport3D = XamlReader.Load(mysr.BaseStream) as Viewport3D;
You can't manipulate the control tree like that. You should instead be appending elements.
First, remove the Viewport3D from your XAML.
Second, give your grid a name, say _grid.
Third, change the aforementioned line to:
_grid.Children.Add(XamlReader.Load(mysr.BaseStream) as Viewport3D);
This is the appropriate way to manipulate the control tree.

Related

Vlc.DotNet WPF video background issue

There is my code. I see the video in the top right corner, where control itself is located, but the main grid background is empty. It's supposed to take video through VisualBrush, right? I've googled few samples and they all use the same trick, but it doesn't work...
I've also tried to put some controls on top of the control, but nothing shows through, because I assume it's using WinForms control inside, which is top-most.
So how do I get this video as the background?
<Grid>
<vlc:VlcControl x:Name="myVlcControl" Width="100" Height="100" HorizontalAlignment="Right" VerticalAlignment="Top" />
<Grid>
<Grid.Background>
<VisualBrush Stretch="Uniform">
<VisualBrush.Visual>
<Image Source="{Binding VideoSource, ElementName=myVlcControl}" />
</VisualBrush.Visual>
</VisualBrush >
</Grid.Background>
</Grid>
MediaElement supports RTSP just fine, but it may not support the encoding/container you're trying to work with. The following produces a working streaming MediaElement, and uses a VisualBrush to paint the background of a Grid with the MediaElement:
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<MediaElement x:Name="MyPlayer"
Width="640"
Height="480"
LoadedBehavior="Play"
Source="rtsp://granton.ucs.ed.ac.uk/domsdemo/v2003-1.wmv" />
<Grid Grid.Row="1"
Width="320"
Height="240">
<Grid.Background>
<VisualBrush Stretch="Uniform" Visual="{Binding ElementName=MyPlayer}" />
</Grid.Background>
</Grid>
</Grid>
#Kolorowezworki made Airhack control to workaround this issue.
Example:
<airhack:AirControl DataContext="{Binding}">
<airhack:AirControl.Front>
<Image Source="{Binding VideoSource, ElementName=myVlcControl}" />
</airhack:AirControl.Front>
<airhack:AirControl.Back>
<vlc:VlcControl x:Name="myVlcControl" Width="100" Height="100" HorizontalAlignment="Right" VerticalAlignment="Top" />
</airhack:AirControl.Back>
</airhack:AirControl>
NOTE: By default AirControl does't support DataContext Binding, to solve this issue fork or copy repository and implement DataContext support by passing it 'airhack' window.
Example:
public AirControl()
{
InitializeComponent();
alpha = new Alpha(this);
alpha.DataContext = DataContext;
DataContextChanged += (sender, args) => alpha.DataContext = DataContext;
}

Can width of TextBox be set using FormattedText.MinWidth?

Banging my head trying to figure this out. The goal is to create a wrapping TextBox at a given location where the width is set to that of the largest word in the string of text. FormattedText.MinWidth calculates the width of the largest word in the string. But passing that MinWidth to the TextBox causes the TextBox to be slightly too narrow. TextBlock does not have this problem.
Evidentally something is happening deep down inside the TextBox causing this behavior. I can't just add a fixed magic number to the TextBox width because the increase in the width needed to correct the problem will always differ based on the pixel width of the character that was wrapped to the next line. The number of pixels will always differ depending on what that character is, the font, and font size.
If someone has more reputation could you please add FormattedText and MinWidth as a tag? Restrictions won't let me, a stupid first post newbe, do this. I also would like to have added an image which would make this sooo much easier to understand but stupid restrictions (did I say that?) prevent me from doing so.
namespace FormattedTextExample
{
public partial class FormattedText1 : Window
{
string noteText =
"We hold these truths to be self-evident, that all men are created equal, that they " +
"are endowed by their Creator with certain unalienable Rights, that among these are " +
"Life, Liberty and the pursuit of Happiness.--That to secure these rights, Governments " +
"are instituted..";
public FormattedText1()
{
InitializeComponent();
myText.Text = noteText;
}
protected override void OnRender(DrawingContext drawingContext)
{
FormattedText ft = new FormattedText(
textToFormat: noteText,
culture: CultureInfo.GetCultureInfo("en-us"),
flowDirection: myText.FlowDirection,
typeface: new Typeface(myText.FontFamily.ToString()),
emSize: myText.FontSize,
foreground: myText.Foreground);
ft.MaxTextWidth = ft.MinWidth;
DrawingContext dc = drawDest.Open();
dc.DrawText(ft, new Point(0, 0));
dc.Close();
myDrawingBrush.Drawing = drawDest;
myText.Width = ft.MinWidth;
}
}
}
<Window x:Class="FormattedTextExample.FormattedText1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="FormattedText" Height="500" Width="500">
<DockPanel>
<Grid DockPanel.Dock="Top" ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="0">
<Rectangle.Fill>
<DrawingBrush x:Name="myDrawingBrush" Stretch="None"
AlignmentY="Top" AlignmentX="Left" >
<DrawingBrush.Drawing>
<DrawingGroup x:Name="drawDest" />
</DrawingBrush.Drawing>
</DrawingBrush>
</Rectangle.Fill>
</Rectangle>
<StackPanel Grid.Column="1">
<TextBox x:Name="myText" TextWrapping="Wrap" />
<!-- Everything works fine if using TextBlock -->
<!--<TextBlock x:Name="myText" TextWrapping="Wrap" />-->
</StackPanel>
</Grid>
</DockPanel>
</Window>
The reason your textbox needs more space is the way its control template is defined.
This is how the default control template looks like (from MSDN):
<ControlTemplate TargetType="{x:Type TextBoxBase}">
<Border Name="Border"
BorderThickness="1"
CornerRadius="2"
Padding="2">
<Border.Background>
<SolidColorBrush Color="{DynamicResource ControlLightColor}" />
</Border.Background>
<Border.BorderBrush>
<SolidColorBrush Color="{DynamicResource BorderMediumColor}" />
</Border.BorderBrush>
<!-- VisualStateManager code -->
<ScrollViewer x:Name="PART_ContentHost" Margin="0" />
</Border>
</ControlTemplate>
Studying the default control template or defining your own helps determining exactly how much extra space do you need to allocate to your text box.

How to make a multipaged UserControl in WPF?

I'm trying to make a user control which contains three different pages, each displaying different content. My idea was to make the following: create the user control main grid, then create another grid with the width set to three times the width of the user control or the main grid, and then create three columns in it. Then I would create a grid for each of the columns, wrapping each page content. Next, create two buttons to slide the pages, changing them through a translate transform animation.
I did it all right, but the sliding doesn't work as I expected: when the grid is translated, the content of the new page doesn't get displayed, and the other page keeps visible in the side of the user control.
The code is as follows:
.cs
private void TranslateMainGrid(bool right)
{
DoubleAnimation gridTranslateAnimation = new DoubleAnimation(); // Calculations not important
gridTranslateAnimation.From = right ? 0 - (this.SelectedPanel - 1) * 286 : 0 - (this.SelectedPanel + 1) * 286;
gridTranslateAnimation.To = 0 - this.SelectedPanel * 286;
gridTranslateAnimation.Duration
= new Duration(new TimeSpan(0, 0, 0, 0, 500));
TranslateTransform oTransform
= (TranslateTransform)PanelGrid.RenderTransform;
oTransform.BeginAnimation(TranslateTransform.XProperty,
gridTranslateAnimation);
}
.xaml
<Grid x:Name="MainGrid" Height="400" Width="286" Background="#7B9D9D9D" RenderTransformOrigin="0.5,0.5">
<Grid x:Name="PanelGrid" Height="400" Width="858" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<TranslateTransform X="0"/>
</Grid.RenderTransform>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid x:Name="ChimeraGrid" Grid.Column="0">
<Grid.Background>
<ImageBrush ImageSource="/GameView;component/Resources/arcaneCreature.png"/>
</Grid.Background>
</Grid>
<Grid x:Name="CreatureGrid" Grid.Column="1">
<Grid.Background>
<ImageBrush ImageSource="/GameView;component/Resources/chimeraTest.png"/>
</Grid.Background>
<Label Content="lolololol" Height="81" VerticalAlignment="Top" HorizontalAlignment="Right" Width="164"/>
</Grid>
<Grid x:Name="EquipmentGrid" Grid.Column="2">
<Grid.Background>
<ImageBrush ImageSource="/GameView;component/Resources/tribeCreature.png"/>
</Grid.Background>
</Grid>
</Grid>
</Grid>
The code was simplified, but I guess it ilustrates the whole stuff. How can I deal with this grids? Is there any other way to do what I intended here?
Thanks
Replace your top-level Grid
<Grid x:Name="MainGrid" Width="286" ...>
by a Canvas and set the ClipToBounds property:
<Canvas Name="MainCanvas" Width="286" ClipToBounds="True">
Moreover you have to set the Height property of those Grids in the three columns that don't have any content. Setting only the Background to an ImageBrush will not affect the Grid's size. The result is that the three Grids have Width=286 (resulting from 858 divided by three columns) but the left and right Grid have Height=0, because they have no content. The middle one gets its height from the contained Label and is hence visible.
Instead of setting an ImageBrush you could also put an Image control in each column Grid. Thus the heights of the three Grids would be set automatically.
Of course ClipToBounds also works with a Grid, but it seems that the Grid won't re-render any previously invisible parts of its content when a RenderTransform is applied to that content.
When using a Canvas you may also consider to animate the Canvas.Left property instead of using a TranslateTransform.
EDIT: Here is the XAML from my test program:
<Window x:Class="SlidingGrid.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="500" Width="400">
<Canvas Width="286" ClipToBounds="True" Margin="10">
<Grid Width="858" Name="grid" Canvas.Left="0" Height="400">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RenderTransform>
<TranslateTransform x:Name="slideTransform"/>
</Grid.RenderTransform>
<Grid Grid.Column="0">
<Grid.Background>
<ImageBrush ImageSource="C:\Users\Public\Pictures\Sample Pictures\Desert.jpg" Stretch="UniformToFill"/>
</Grid.Background>
</Grid>
<Grid Grid.Column="1">
<Grid.Background>
<ImageBrush ImageSource="C:\Users\Public\Pictures\Sample Pictures\Penguins.jpg" Stretch="UniformToFill"/>
</Grid.Background>
</Grid>
<Grid Grid.Column="2">
<Grid.Background>
<ImageBrush ImageSource="C:\Users\Public\Pictures\Sample Pictures\Tulips.jpg" Stretch="UniformToFill"/>
</Grid.Background>
</Grid>
</Grid>
</Canvas>
</Window>
and the code:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Loaded += (o, e) =>
{
//grid.BeginAnimation(
// Canvas.LeftProperty,
// new DoubleAnimation(-572, TimeSpan.FromSeconds(2)));
slideTransform.BeginAnimation(
TranslateTransform.XProperty,
new DoubleAnimation(-572, TimeSpan.FromSeconds(2)));
};
}
}

Strange behavior on ShowDialog in WPF

I create separate Window, design it with XAML and when I invoke ShowDialog from main form it seems like my dialog (Window) blinks once and then shows itself. Is it a common behavior? I didn't notice that in while working with Windows Forms. I also ran application on another computer, and get the same thing. It bothers me, cause I was developing a simple game, and it's not the effect I would like users to experience.
It is not a complicated dialog, considering the design. It contains just label and button. Here is one sample:
<Window x:Class="A_Boggle.Info"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Info" Height="300" Width="670" AllowsTransparency="True" WindowStyle="None" Background="Transparent" BorderBrush="Transparent" Foreground="Transparent" ShowInTaskbar="False" ResizeMode="NoResize" WindowStartupLocation="CenterScreen" Closing="Window_Closing">
<Grid>
<Border Background="Transparent" Visibility="{Binding Visibility}">
<Border BorderBrush="#FF7C4400" BorderThickness="4"
CornerRadius="10,0,10,0" VerticalAlignment="Center" HorizontalAlignment="Center" Height="177.5" Width="596.25">
<Border.Background>
<RadialGradientBrush Center="0.5,0.5" GradientOrigin="0.5,0.5" RadiusX="0.479" RadiusY="0.524">
<GradientStop Color="#FFF58611" Offset="0"/>
<GradientStop Color="#FFF58611" Offset="0.11798000335693359"/>
<GradientStop Color="#FFE9B231" Offset="1"/>
</RadialGradientBrush>
</Border.Background>
<Border.BitmapEffect>
<DropShadowBitmapEffect Color="Black" Opacity="0.5" Direction="270" ShadowDepth="0.7" />
</Border.BitmapEffect>
<Grid>
<Separator Height="20" Name="separator1" Margin="8.75,0,6.25,45" VerticalAlignment="Bottom" />
<Button Style="{DynamicResource OrangeButton}" Margin="406.25,0,6.25,6" Height="37.75" VerticalAlignment="Bottom" FontSize="16" Name="dialogButton" Click="dialogButton_Click"></Button>
<Label FontFamily="Resources/#French Grotesque" FontSize="20" Foreground="#FF7C4400" Margin="8.75,20,6.25,71.25" Name="messageLabel"></Label>
</Grid>
</Border>
</Border>
</Grid>
No. Blinking on ShowDialog is not a common behaviour. Could you first try with an empty Window:
new Window().ShowDialog();
in order to see if the problem persists?
Aside from the main topic, WPF/XAML might be not the proper technology for a complicated game due to performance reasons (although for a simple one must be OK).

How to position UserControl in the parent canvas

I want to place this UserControl at Canvas.Left="168", Canvas.Top="213".
However, the control appears at a corner. What should I do?
If I put the values at the point of usage for this class, the values are returned as NaN
In that case how can I get the correct Left and Top Values?
Usage:
<Canvas x:Name="DesignerCanvas"
ClipToBounds="True"
SnapsToDevicePixels="True">
<Gr:BareNode />
</Canvas>
UserControl:
<UserControl x:Class="DiagramDesigner.BareNode"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<ContentControl Width="50"
Height="50"
Padding="2"
Canvas.Left="168" Canvas.Top="213">
<Ellipse IsHitTestVisible="False" >
<Shape.Fill>
<RadialGradientBrush Center="0.2, 0.2" GradientOrigin="0.2, 0.2" RadiusX="0.8" RadiusY="0.8">
<GradientStop Color="LightBlue" Offset="0"/>
<GradientStop Color="Blue" Offset="0.9"/>
</RadialGradientBrush>
</Shape.Fill>
</Ellipse>
</ContentControl>
</Grid>
</UserControl>
I'm not sure if you tried this or not, but just from looking at the XAML it appears that you are trying to set the position of the user control inside the user control. That won't work. You need to put it where you use the user control
<Canvas x:Name="DesignerCanvas"
ClipToBounds="True"
SnapsToDevicePixels="True">
<Gr:BareNode Canvas.Left="168" Canvas.Top="213"/>
</Canvas>
Take the Canvas.Left="168" Canvas.Top="213" part out of the ContentControl declaration of inside the user control.

Resources