XAML margin error - c#

I am trying to generate a dynamic form on windows universal app and having a problem with the margin.
I like to keep both Radiobutton and Textbox to be on the left side at margin 0.
The problem is somehow the Textbox can't stay on the left, i have both controls with the margin left at 0, somehow the textbox was pushing to the right of the screen.
This is the result after I ran the app.
The output result for Windows Universal app on Windows 10
My script file name MainPage.xaml.cs for project AppTestTrash
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
namespace AppTestTrash
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
//Add dynamic RadioButton
var dynamicRadiobtn = new RadioButton();
dynamicRadiobtn.Name = "testme";
dynamicRadiobtn.Height = 30;
dynamicRadiobtn.Width = 50;
dynamicRadiobtn.Margin = new Thickness(0, 100, 0, 0);
dynamicForm.Children.Add(dynamicRadiobtn);
//Add dynamic texbox
var dynamicTextbox = new TextBox();
dynamicTextbox.Name = "testme2";
dynamicTextbox.Height = 30;
dynamicTextbox.Width = 50;
dynamicTextbox.Margin = new Thickness(0, 120, 0, 0);
dynamicForm.Children.Add(dynamicTextbox);
}
}
}
XAML file mainpage.xaml
<Page
x:Class="AppTestTrash.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:AppTestTrash"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" Loaded="Page_Loaded">
<Grid Name="mainGrid" BorderBrush="AliceBlue" Width="500" Height="500" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" BorderThickness="2">
<StackPanel Name="dynamicForm" BorderThickness="1">
</StackPanel>
</Grid>
</Page>

To solve this issue, you can set dynamicTextbox's HorizontalAlignment property to Left like the following.
//Add dynamic texbox
var dynamicTextbox = new TextBox();
dynamicTextbox.Name = "testme2";
dynamicTextbox.Height = 30;
dynamicTextbox.Width = 50;
dynamicTextbox.HorizontalAlignment = HorizontalAlignment.Left;
dynamicTextbox.Margin = new Thickness(0, 120, 0, 0);
dynamicForm.Children.Add(dynamicTextbox);
The default value of HorizontalAlignment is Stretch, so your text box will be on the center of your grid even the left margin is 0. For more info, please see Remarks of HorizontalAlignment.

Related

UWP: use 1 MediaSource for several Players

I have some uwp application, where several videos are played simultaneously. I thought it might be a good idea to use 1 media source to improve performance. But I'm not sure why this idea doesn't work.
MainPage.xaml:
<Page
x:Class="UWP_OneMediaSourceForSeveralPlayers.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UWP_OneMediaSourceForSeveralPlayers"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
Loaded="Page_Loaded">
<StackPanel Orientation="Vertical" Background="Yellow" Height="400" Width="200">
<MediaPlayerElement x:Name="Player1" Height="200" Width="200" />
<MediaPlayerElement x:Name="Player2" Height="200" Width="200" />
</StackPanel>
</Page>
MainPage.xaml.cs:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Media.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
namespace UWP_OneMediaSourceForSeveralPlayers
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
var uri = new Uri(BaseUri, "/Assets/Videos/video.mp4");
var mediaSource = MediaSource.CreateFromUri(uri);
Player1.Source = mediaSource;
Player2.Source = mediaSource;
Player1.MediaPlayer.Play();
Player2.MediaPlayer.Play();
}
}
}
That's what I see:
So, looks like the first video is loaded. But not the second...
NOW question: why I can not use 1 media source for 2 players? How to make it work? Or do you have any other idea how to run the same file in several players?
P.S. creating 2 media sources from URI is not a good solution for me, because my app can have a lot (10+) videos running at the same time. If I create a media source for each player it will hurt performance.
So what you can actually do here is share a MediaPlayer between the two MediaPlayerElement instance.
private void Page_Loaded(object sender, RoutedEventArgs e)
{
var uri = new Uri(BaseUri, "/Assets/Videos/video.mp4");
var mediaSource = MediaSource.CreateFromUri(uri);
var player = new MediaPlayer
{
Source = new MediaPlaybackItem(mediaSource)
};
Player1.SetMediaPlayer(player);
Player2.SetMediaPlayer(player);
player.Play();
}
If you don't require the transport controls from MediaPlayerElement, it's probably better to use MediaPlayerPresenter instead.

Member 'Storyboard.SetTargetName(DependencyObject, string)' cannot be accessed with an instance reference; qualify it with a type name instead

I am trying to make a startup animation for my WPF Application. And I get the following message:
error
And this is my current code:
code
I think you can use code like this
Storyboard.SetTargetName(startupAnimation1da, loadingWindow.Name);
Instead of
startupAnimation1.SetTargetName(startupAnimation1da, loadingWindow.Name);
Also, I don't think your code will run correctly, I think it will not do the animation. Because you created the DoubleAnimation, but did not set the target property that it needs to change. You can use Storyboard.SetTargetProperty() method to set it like this:
Storyboard.SetTargetProperty(ANIMATION, PROPERTY);
And an example:
Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath(Button.WidthProperty));
Here is an example below of use Storyboard.SetTargetName() and Storyboard.SetTargetProperty() methods.
It is an animation of change button width.
Xaml:
<Window x:Class="WpfTestApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Button x:Name="AnimationButton" Height="34" Width="100" Content="Begin" Click="AnimationButton_Click"></Button>
</Window>
C#:
using System;
using System.Windows;
using System.Windows.Media.Animation;
using System.Windows.Controls;
namespace WpfTestApp
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void AnimationButton_Click(object sender, RoutedEventArgs e)
{
//Create the animaton
Storyboard storyboard = new Storyboard();
DoubleAnimation doubleAnimation = new DoubleAnimation
{
From = 100,
To = 300,
Duration = new Duration(new TimeSpan(0, 0, 1)),
AutoReverse = true,
RepeatBehavior = RepeatBehavior.Forever
};
storyboard.Children.Add(doubleAnimation);
//Set taeget name
Storyboard.SetTargetName(doubleAnimation, "AnimationButton");
//Set target property
Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath(Button.WidthProperty));
//Begin the animaton
storyboard.Begin(AnimationButton);
}
}
}

I get error: name cannot be found in the name scope of - When moving from page to page in an MVVMLight application

I have an MVVMLight multi-page application which has two pages, I can navigate from one page to the other by clicking the respective buttons.
In the second page, I have a loader animation that is triggered every time something is typed in a textBox field. Everything is working fine; from the first page I can go to the second page then you type something in the textBox and the animation starts. The problem is that if I go to the second page, then I go back to the first page and then I go to the second page again and type something in the textBox I get an error that says that the name of the loader doesn't exist, the funny thing is that I don't get this error until I leave the page and come back.
Any idea why the animation stops working after leaving the page and coming back?
EDIT: Here is the link to a complete project.
https://www.dropbox.com/sh/yf87shw5rzxtxen/AAClTesIGpLKl6IzV-6pjfEfa?dl=0
To replicate error do the following...
Download and open application.
Go to page 2.
Type something in the textBox (animation should start).
Go back to page 1, do nothing.
Go to page 2 again and try typing something in the textBox (you should see the error here).
Error:
Additional information: 'rectangleLoader' name cannot be found in the name scope of 'TwoViews.Views.SecondView'.
XAML
<UserControl x:Class="TwoViews.Views.SecondView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="300"
d:DesignWidth="300"
mc:Ignorable="d">
<Grid>
<Rectangle x:Name="rectangleLoader" Fill="#FFB2B2FF" HorizontalAlignment="Left" Height="19" Margin="26,89,0,0" VerticalAlignment="Top" Width="248"/>
<TextBox x:Name="textBoxFileName"
HorizontalAlignment="Left"
Height="35" Width="180"
Margin="26,125,0,0"
VerticalAlignment="Top"
Text="{Binding InputFileNameChanged, UpdateSourceTrigger=PropertyChanged}" FontSize="18"/>
</Grid>
</UserControl>
SecondView.xaml.cs
namespace TwoViews.Views
{
public partial class SecondView : UserControl
{
private Storyboard loaderStoryboard;
public SecondView()
{
InitializeComponent();
Messenger.Default.Register<MessageSearchStatus>(this, messageSearchStatus => ReceivedSearchStatus(messageSearchStatus));
/// Animation for loader
DoubleAnimation myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = 100;
myDoubleAnimation.To = 0;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(.1));
myDoubleAnimation.AutoReverse = true;
myDoubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
loaderStoryboard = new Storyboard();
loaderStoryboard.Children.Add(myDoubleAnimation);
Storyboard.SetTargetName(myDoubleAnimation, rectangleLoader.Name);
Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(Rectangle.WidthProperty));
}
private void ReceivedSearchStatus(MessageSearchStatus message)
{
loaderStoryboard.Begin(this, true);
}
/// I manually stop the animation before going to other screens
private void stopAnimation_Click(object sender, System.Windows.RoutedEventArgs e)
{
loaderStoryboard.Stop(this);
}
}
}
ViewModel
namespace TwoViews.ViewModels
{
public class SecondViewModel : ViewModelBase
{
private string _inputFileName;
public string InputFileNameChanged
{
get { return _inputFileName; }
set {
// send message to start animation everytime the textBox changes
Messenger.Default.Send<MessageSearchStatus>(new MessageSearchStatus { isSearchingFile = true });
}
}
}
}
Please note that in my code I'm not showing the code that stops the animation.
Again, the animation works fine until the user leaves the page where the animation is and comes back.
Thanks!
FYI - The issue appeared to be the Storyboard I was using with the animation. Removed the Storyboard and everything work fine.
SecondView.xaml.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;
using System;
using System.Windows.Input;
using GalaSoft.MvvmLight.Messaging;
using GalaSoft.MvvmLight.Threading;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Collections.Specialized;
using System.Linq;
using System.Windows.Shapes;
using TwoViews.Models;
using System.Windows.Media;
namespace TwoViews.Views
{
public partial class SecondView : UserControl
{
private DoubleAnimation myDoubleAnimation;
public SecondView()
{
InitializeComponent();
Messenger.Default.Register<MessageSearchStatus>(this, messageSearchStatus => ReceivedSearchStatus(messageSearchStatus));
/// Animation for loader
myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = 100;
myDoubleAnimation.To = 0;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(.1));
myDoubleAnimation.AutoReverse = true;
myDoubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
}
private void ReceivedSearchStatus(MessageSearchStatus message)
{
rectangleLoader.BeginAnimation(Rectangle.WidthProperty, myDoubleAnimation);
}
private void stopAnimation_Click(object sender, System.Windows.RoutedEventArgs e)
{
rectangleLoader.BeginAnimation(Rectangle.WidthProperty, null);
}
}
}

Changing image in Window Application (WPF)

Goal: Changing an image to another one when a red button is clicked.
But there is a problem when changing initial panda image to animation character image.
panda image is set up in the mainpage.xaml.
<Page
x:Class="App3.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App3"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Button Height="100" Width="100" Click="Button_Click" Background="#FFEA2323"/>
<Image x:Name="image" Source="Images/panda1.png" Margin="436,170,418,174"/>
</Grid>
</Page>
And character image is set up when button is clicked
This is "mainpage.xaml.cs" code
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Shapes;
using Windows.UI;
using System.Windows;
// 빈 페이지 항목 템플릿에 대한 설명은 http://go.microsoft.com/fwlink/?LinkId=234238 에 나와 있습니다.
namespace App3
{
/// <summary>
/// 자체에서 사용하거나 프레임 내에서 탐색할 수 있는 빈 페이지입니다.
/// </summary>
///
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
image.Source = new BitmapImage(new Uri(#"C:\Users\hinon\OneDrive\Documents\2016-2\04. 놀이방\03. 키넥트 제스처 기반 게임 제작 환경 구성\03. 데이터베이스\01. 이미지\닥터슬럼프 아리.bmp", UriKind.Absolute));
//BitmapImage bitmapImage = new BitmapImage();
//bitmapImage.UriSource = new Uri(#"C:\Users\hinon\OneDrive\Documents\2016-2\04. 놀이방\03. 키넥트 제스처 기반 게임 제작 환경 구성\03. 데이터베이스\01. 이미지\닥터슬럼프 아리.bmp", UriKind.Absolute);
//image.Source = bitmapImage;
}
}
}
But it is not successful. If I click the button, initial panda image is dissapeared, and no image opend. just black. What I missed in this code?
Before click the red button
After click the red button

WPF how to create tab items

The number of tab items are not predetermined. I just want to create new tab items and then add new rectangles inside current items.
I am generating new tab items(bellow is code) but how can I add rectangles in current tab?
var _FloorName = (from fn in db.floors select fn.floorname).ToList();
if (_FloorName.Count > 0)
{
for (int i = 0; i < _FloorName.Count; i++)
{
tabControl1.Items.Add(_FloorName[i]);
}
}
Here is one approach you could take:
Add a Grid (or other container) to each TabItem when creating them
Create a Rectangle, with the brush/dimensions you want
Call tabControl1.SelectedContent, cast it to Grid (or your container type)
Call grid.Children.Add(rectangle)
Here is a complete code sample (using copious code-behind).
MainWindow.xaml:
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel Margin="12">
<TabControl Name="tabControl1" Height="250" />
<Button Content="Add Rectangle" Click="Button_Click"
Width="90" Height="25" Margin="5" />
</StackPanel>
</Window>
MainWindow.xaml.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
public class Floor
{
public Floor(string name = null)
{
this.Name = name;
}
public string Name { get; set; }
}
public class FakeDb
{
public IEnumerable<Floor> Floors
{
get
{
return new List<Floor>()
{
new Floor("floor1"),
new Floor("floor2"),
new Floor("floor3"),
};
}
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
InitializeTabControl();
}
private void InitializeTabControl()
{
var db = new FakeDb();
var floorNames = (from fn in db.Floors select fn.Name).ToList();
foreach (string floorName in floorNames)
{
var item = new TabItem()
{
Header = floorName,
Content = new Grid(),
};
tabControl1.Items.Add(item);
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var random = new Random();
var rectangle = new Rectangle()
{
Stroke = Brushes.Black,
Fill = Brushes.SkyBlue,
Width = 50,
Height = 75,
Margin = new Thickness(
left: random.NextDouble() * 300,
top: random.NextDouble() * 150,
right: 0,
bottom: 0),
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Top,
};
var grid = (Grid)tabControl1.SelectedContent;
grid.Children.Add(rectangle);
}
}
You should have a look at this article from Josh Smith -
Patterns - WPF Apps With The Model-View-ViewModel Design Pattern
This is one of the best articles explaining MVVM implementation, the sample application developed creates tabs at runtime and uses templates to display the internal contents. If you can go the same way you will have a very stable and expandable application.
Note: Code download available from the MSDN Code Gallery
If this is just adding some control, or draw something on Tab, cause it's not very clear from post, I would personally, strongly recommend to define a Template of TabItem in XAML, as it will save you a lot of "drawing fixes" time. If yuo have a Blender it will become even much easier.
EDIT
If you need some sample with binding and whatever, don't have on my hands now the code, but can provide you with a link to open source project. Have look how TabItems are managed there.
SvnRadar
Regards.

Categories