Grid Layout Change at runtime Xamarin - c#

I show 4 button, at Row=0/Column=0, Row=0/Column=1, Row=1/Column=0, and Row=1/Column=1, I want to see 3 buttons equally taking. Im doing in Xamarin Forms Platform
<Grid x:Name="grid">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Text="Change Layout1" ></Button>
<Button Grid.Row="1" Text="Change Layout2" ></Button>
<Button Grid.Row="0" Grid.Column="1" Text="Change Layout3" ></Button>
<Button Grid.Row="1" Grid.Column="1" Text="Change Layout4" ></Button>
</Grid>
On Dynamic Change i want to rearrange the grid when one button is removed,
private void Button_Clicked(object sender, EventArgs e)
{
grid.Children.RemoveAt(1);
}
Can anyone suggest your ideas

When a button is clicked, I remove one of the grid items, and then need to rearrange the remaining items automatically. To achieve this, I’m using SetRowSpan() and SetRow().
private void Button_Clicked(object sender, EventArgs e)
{
grid.Children.RemoveAt(1);
Grid.SetRowSpan(button4,2);
}

Related

How to make a custom Pop Up Dialogue reuseable

So I created a custom Pop Up dialogue box in UWP, to make it reusable, i made use it of a User Control
<UserControl
x:Class="ContentDialogueBox.PopUpCustomDialogueUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ContentDialogueBox"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<ContentDialog x:Name="MyContentDialogCustom"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Title="Lorem Ipsum"
PrimaryButtonText="OKxxx"
SecondaryButtonText="Canc"
Margin="0,0,-98,0" Width="1000" >
<Grid Background="Wheat">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Text="Name" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBox PlaceholderText="First Name" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Center" Margin="10"/>
<TextBlock Text="Middle Name" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="1"/>
<TextBox PlaceholderText="Middle Name" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Center" Margin="10"/>
<TextBlock Grid.Row="2" Text="Name" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBox PlaceholderText="First Name" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Center" Margin="10"/>
</Grid>
</ContentDialog>
</UserControl>
I was able to reference the user control in another page that contains the button named ButtonShowContentDialog4, what i want to achieve is display the PopUp Dialogue box, when i click the button in the page. Please how do i achieve this.
private void ButtonShowContentDialog4_Click(object sender, RoutedEventArgs e)
{
//show the PopUp here when this button is clicked
}
There are couple of ways to achieve that. Apart from the thing that you could have made a custom ContentDialog instead of putting it inside the user control, you can probably achieve your goal like this:
In your PopUpCustomDialogueUserControl class define a method that would show your popup:
public async Task ShowMyDialog() => await MyContentDialogCustom.ShowAsync();
Once you have it, add your PopUpCustomDialogueUserControl somwhere in your Page in xaml (remember to have a suitable namespace added (ContentDialogueBox) defined below as local) and add it a Name:
<local:PopUpCustomDialogueUserControl x:Name="MyCustomDialog"/>
Then you can call its method in code:
private async void ButtonShowContentDialog4_Click(object sender, RoutedEventArgs e)
{
await MyCustomDialog.ShowMyDialog();
}

How do you overlay a control over a grid that it is not in (xaml/wpf)

I have a grid that serves as a drag/drop area between textboxes, however, placing it between them causes the textboxes to be displaced. How can I get it so that the drag/drop grid is behind the text boxes, instead of in between them?
The first grid is the drag/drop area and below is the code for the textboxes:
<Grid Grid.Column="0" Height="Auto" Width="20" AllowDrop="True" Background="White"
DragEnter="Grid_DragEnter" DragLeave="Grid_DragLeave" Drop="Grid_Drop" Tag="{Binding}"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock HorizontalAlignment="Left" Margin="5,2"
Text="some text"
VerticalAlignment="Center" FontSize="5" />
</Grid>
A picture of what I mean, where the black boxes are the textboxes, and everything enclosed in the red is the grid area where things can be dragged and dropped.
This works for me. Code behind is a mild bummer, especially referencing the droptarget by name. It would be easy to turn that into an attached property that you bind to the droptarget element, which would be convenient for use in templates etc. Anyhow you can't do drag/drop without codebehind, so there you are. Sometimes life gives you codebehind. Use it to, uh, make, um, lemons.
A lot of this XAML is just fussing around to make the elements overlap each other the way yours do. The Grid.Column/Grid.ColumnSpan stuff is important for the overlapping layout you have in mind.
Note that the TextBoxes use the PreviewDragOver event, not DragOver. DragOver wasn't being raised. Not sure if that's a bug or my faulty understanding, but a lot of people seem to have run into trouble getting DragOver to work with WPF TextBox.
XAML:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="80,0,80,0"
Height="80"
VerticalAlignment="Center"
HorizontalAlignment="Stretch"
Drop="TextBox_Drop"
DragOver="TextBox_DragOver"
Background="DeepSkyBlue"
x:Name="DropTargetGrid"
AllowDrop="True"
></Grid>
<TextBox
Grid.Column="0"
Margin="40,40,10,40"
Drop="TextBox_Drop"
PreviewDragOver="TextBox_DragOver"
AllowDrop="True"
VerticalAlignment="Center"
/>
<TextBox
Grid.Column="1"
Margin="10,40,40,40"
Drop="TextBox_Drop"
PreviewDragOver="TextBox_DragOver"
AllowDrop="True"
VerticalAlignment="Center"
/>
</Grid>
Code behind:
private void TextBox_Drop(object sender, DragEventArgs e)
{
// Do whatever
}
private void TextBox_DragOver(object sender, DragEventArgs e)
{
var ptTargetClient = e.GetPosition(DropTargetGrid);
if (ptTargetClient.X >= 0 && ptTargetClient.X <= DropTargetGrid.ActualWidth
&& ptTargetClient.Y >= 0 && ptTargetClient.Y <= DropTargetGrid.ActualHeight)
{
e.Handled = true;
e.Effects = DragDropEffects.Move;
}
}

Getting time of the freeze frame in WPF

I want to get a time of a freeze frame of a video which is paused by the pause button in WPF. I want to store time of that freeze frame and use it in the future. How do i get a perfect time of that specific frame? What type of variable i should use to store that time?
I'd use the Position property, which returns a TimeSpan:
XAML
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<MediaElement x:Name="MyMediaElement"
Grid.Row="0"
LoadedBehavior="Manual"
Source="SomeDrive:\SomeFolder\SomeMediaFile.mp4" />
<StackPanel Grid.Row="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Horizontal">
<Button Width="50"
Height="50"
Click="PlayMedia"
Content="Play" />
<Button Width="50"
Height="50"
Click="PauseMedia"
Content="Pause" />
<TextBlock x:Name="MyTextBlock"
FontSize="30"
Text="0" />
</StackPanel>
</Grid>
Codebehind
private void PlayMedia(object sender, RoutedEventArgs e)
{
MyMediaElement.Play();
}
private void PauseMedia(object sender, RoutedEventArgs e)
{
MyMediaElement.Pause();
var currentTime = MyMediaElement.Position;
MyTextBlock.Text = currentTime.ToString();
}
I believe you are after the Clock property of the MediaElement.
See the documentation.
You can access the CurrentTime property. See more documentation.

wpf user control - how to set text from outer uc

i have a problem , i have 2 uc that displayed in main windows.
i want when i press on button in the first uc the text in the other uc will change
this the axml i use and the code
first uc
<Grid.RowDefinitions>
<RowDefinition ></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Width="40" Height="40" Name="playbtn" HorizontalAlignment="Left" Grid.Row="0" Grid.Column="0" Click="playbtn_Click" >
<Button.Content>
<Image Source="/img/player_play.png" ></Image>
</Button.Content>
</Button>
<Button Width="40" Height="40" Name="pausebtn" Grid.Column="1" Grid.Row="0" >
<Button.Content>
<Image Source="/img/player_pause.png" ></Image>
</Button.Content>
</Button>
<Button Width="40" Height="40" Name="stopbtn" Grid.Column="2" Grid.Row="0" >
<Button.Content>
<Image Source="/img/player_stop.png" ></Image>
</Button.Content>
</Button>
</Grid>
</StackPanel>
</Grid>
</StackPanel>
secound uc <TextBlock Name="Progresstimertext" Text="00:00:00" FontSize="20"></TextBlock>
so i want to press on start button and the timer will be change? how to
10x
This should be managed in the View Model of your Main Window, as this seems the only location that has knowledge of both controls and it sounds as though each of your user control's shouldn't necessarily have knowledge of each other.
Ideally, you should have a reference to each of your user controls in the code-behind (or view model class is you have a dedicated one).
If in code behind, you would simply expose these by giving them names.
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="your controls reference here">
<Grid>
<Grid.ColumnDefinitions>
</ColumnDefinition>
</ColumnDefinition>
</Grid.ColumnDefinitions>
<controls:UserControl1 x:Name="Control1"/>
<controls:UserControl2 x:Name="Control2" Grid.Column="1"/>
</Grid>
</Window>
Now you can reference them in your code behind by name Control1 and Control2. These user control classes should be exposing the properties that you want to control, in your case ProgressTimerText, such that, in the code-behind, you can set it easily such as
Control2.ProgressTimerText = "00:00:00";
Where to do this? Well you probably want to create a Stopped event on your Control1, that you can attach to your code behind - in your case, something like Stopped. In your UserControl1 class you should declare something like
public event EventHandler Stopped;
And then in the local event handler for the Click of the stop button, invoke that event.
private void Stop_Click(object sender, RoutedEventArgs e)
{
if (Stopped != null)
Stopped(this, e);
}
Attach that in your MainWindow:
<controls:UserControl1 x:Name="Control1" Stopped=Control1_Stopped/>
Now in your code-behind you should have something like:
private void Control1_Stopped(object sender, RoutedEventArgs e)
{
Control2.ProgressTimerText = "00:00:00";
}

WPF ListView with buttons on each line

I have a list of Games which just has an ID, a Date, and a Time.
I am setting this list as the DataContext.
I then have a DataTemplate for these games that is:
<DataTemplate DataType="{x:Type loc:Game}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="100"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Name="dateBlock" Grid.Column="0" Grid.Row="1"
Text="{Binding Date, StringFormat=d}"></TextBlock>
<TextBlock Name="TimeBlock" Grid.Column="1" Grid.Row="1"
Text="{Binding Time}"></TextBlock>
//need to but a button here for each row
</Grid>
</DataTemplate>
To use the template, I am simply just doing this:
<ListBox ItemsSource="{Binding}"></ListBox>
I need to add a Button to each line in this list view that have the same click event, but will somehow pass the ID of the game for which button is being clicked.
How can I do this? I am stuck.
If it doesn't make sense let me know and I will try to explain better.
For the first part, add a Button to the DataTemplate and subscribe to the Click event
<DataTemplate DataType="{x:Type loc:Game}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="100"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Name="dateBlock" Grid.Column="0" Grid.Row="1" Text="{Binding Date, StringFormat=d}"></TextBlock>
<TextBlock Name="TimeBlock" Grid.Column="1" Grid.Row="1" Text="{Binding Time}"></TextBlock>
<Button Click="Button_Click">X</Button>
</Grid>
</DataTemplate>
In the code behind event handler, you can get the DataContext of the clicked Button and find out the Id like
private void Button_Click(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
Game game = button.DataContext as Game;
int id = game.ID;
// ...
}
Easily. Add a Button to your DataTemplate, give it a Command and then set the CommandParameter="{Binding}". The DataContext within a DataTemplate is the object.
As requested, some links to using commands.
WPF Commands Part 1: Basics
WPF Commands Part 2: Command Bindings and Gestures
MSDN Understanding Routed Events and Commands In WPF (ADVANCED)
HTH,
With a ListBox.ItemTemplate. Then in your click event you can get the object via DataContext.
<ListBox.ItemTemplate>
<DataTemplate>
<Button Content="^" IsEnabled="{Binding Path=IsNotFirst, Mode=OneWay}"
Click="btnMoveFDAup"/>
</DataTemplate>
</ListBox.ItemTemplate>
private void btnMoveFDAup(object sender, RoutedEventArgs e)
{
Button btn = ((Button)sender);
// btn.DataContext will get you to the row object where you can retrieve the ID
}

Categories

Resources