i have a 100 * 100 grid on one of the page in my app. i have a single checkbox on the top right of the grid.
what i want is that when the user tap or click on the grid first time the checkbox become checked and when i again taps on the grid the checkbox becomes unchecked. how can i achieve it? i am talking about the metro type checkboxes here. or could i use checkbox itself in this manner? is grid the right way to go?
In short i need some guidelines in solving the above problem?
This may work for you
<Grid Height="100" Width="100" Background="Beige" Tap="Grid_Tap" >
</Grid>
<CheckBox x:Name="gridCheckBox" Content="CheckBox" HorizontalAlignment="Left" Margin="369,47,0,0" VerticalAlignment="Top"/>
then for making the checkbox checked and unchecked on the tap event of the grid we need to add the following code
private void Grid_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
if (gridCheckBox.IsChecked == true)
{
gridCheckBox.IsChecked = false;
}
else
{
gridCheckBox.IsChecked = true;
}
}
gridcheckbox.IsChecked = (gridcheckbox.IsChecked == true) ? false : true;
Related
I have a simple dialog with a SpinEdit and two buttons: OK_Button and Cancel_Button. I've set a mask for the value in the SpinEdit and the dialog won't let me press the cancel button when the value is invalid. I've tried changing the SpinEdit's property to InvalidValueBehavior="AllowLeaveEditor" but then I can click both, OK and cancel button. Is there a way to ONLY allow pressing cancel when the value is incorrect?
XAML:
<dxe:SpinEdit x:Name="dxSpinEdit"
Height="23" MinWidth="200" Width="Auto"
HorizontalAlignment="Right"
Text="{Binding Value, Mode=TwoWay}"
MaskType="Numeric"
IsFloatValue="{Binding FloatValue}"
MinValue="{Binding MinValue}"
MaxValue="{Binding MaxValue}"
Mask="{Binding Mask, Mode=OneWay}"
MaxLength="{Binding Path=InputLength}"
MaskShowPlaceHolders="{Binding ShowPlaceHolder}"
InvalidValueBehavior="WaitForValidValue"
/>
<StackPanel Grid.Row="1" x:Uid="OKCancel_Buttons" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Bottom">
<Button Height="23" x:Name="OK_Button" Click="OK_Click" Content="OK" IsDefault="True" HorizontalAlignment="Right" MinWidth="95" />
<Button Height="23" x:Name="Cancel_Button" Click="Cancel_Click" Content="Cancel" HorizontalAlignment="Right" MinWidth="95" PreviewMouseDown="win_PreviewMouseDown" />
</StackPanel>
I looked up this issue on the devexpress forum but their solution didn't work for me. I've implemented the MouseDownPreview event like so:
C# (code behind)
private void OK_Click(object sender, RoutedEventArgs e)
{
DialogResult = true;
Close();
}
private void Cancel_Click(object sender, RoutedEventArgs e)
{
DialogResult = false;
Close();
}
private void win_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if(e.Source == Cancel_Button)
{
DialogResult = false;
Close();
}
}
But the event wasn't handled at all. I'd like to keep the property InvalidValueBehavior at the value "WaitForValidValue" but at the same time I'd like to allow pressing the Cancel button.
Even if you're not going to go the full MVVM route, you should switch from using click events to an ICommand implementation that supports CanExecute logic (such as this one from MVVM Light).
Using a command will automatically disable any bound control (e.g. button or menu item) when CanExecute is false. You can then have all the logic for controlling your commands grouped in one place, including validation that will only allow OK to be clicked when your object is in a valid state.
If you just want to go the standard WPF (non MVVM) route, you could add something like this in your window's constructor
public MyView()
{
....
Ok_Button.Command =
new RelayCommand(() => DialogResult = true, // just setting DialogResult is sufficient, no need to call Close()
// put the required validation logic here
() => dxSpinEdit.Value > 0 && dxSpinEdit.Value < 10);
Cancel_Button.Command = new RelayCommand(() => DialogResult = false);
// replace this with the actual event from SpinEdit
dxSpinEdit.ValueChanged += (s,e) => (OK_Button.Command as RelayCommand).RaiseCanExecuteChanged();
}
Yes I know it looks ugly 😀 - I'd suggest following the MVVM design pattern instead. When using MVVM, all of the command functionality belongs in your ViewModel.
Either way, you can then remove all the click and mousedown handlers from your buttons.
I have two toggleButton's, both set to null state, now I want to check if the user ever toggled the button or not.
<StackPanel Height="45" Orientation="Horizontal" Margin="0,20,0,0">
<Label VerticalContentAlignment="Bottom" Content="هل القاعة صالØØ© من Øيث الإستماع؟"/>
<ToggleButton x:Name="ListeningStatusText" IsThreeState="True" IsChecked="{x:Null}" />
</StackPanel>
<StackPanel Height="45" Orientation="Horizontal" Margin="0,20,0,0">
<Label VerticalContentAlignment="Bottom" Content="الإضاءة"/>
<ToggleButton x:Name="LightingStatusText" IsThreeState="True" IsChecked="{x:Null}" />
</StackPanel>
With the code bellow I failled to see if the user never toggle the button:
var ToggleButtonControl = (ToggleButton)ControlName; //
if (ToggleButtonControl.IsChecked == null)
{
parameterStr = "/////////////";
//MessageBox.Show("This should pop-up only if the user never toggled the button");
}
else
{
//MessageBox.Show("The user toggle or toggle it back");
if (ToggleButtonControl.IsChecked == false)
parameterStr = "لا";
else
parameterStr = "نعم";
}
If you want to know if the use has ever toggled the button, attach a function to the Checked and Unchecked event and have a Boolean flag in your class to track that.
The button would look something like this (plus your other attributes):
<ToggleButton
Checked="toggleButton_Changed"
Unchecked="toggleButton_Changed" />
In the function body, set the boolean flag to true, meaning the user has toggled your button. If you want to get the current value, check the button's IsChecked property.
There is no built-in property that you can use to determine whether a ToggleButton has even been toggled. The users can toggle between the true, false and null states as many times they want.
You will need to keep track of this yourself. This should be an easy thing to do though. You could for example handle the Checked and Unchecked events as suggested by #pedrolmota and use a field to keep track of whether these event handlers were ever called:
private bool _hasBeenToggled;
private void ToggleButton_Checked(object sender, RoutedEventArgs e)
{
_hasBeenToggled = true;
}
private void ToggleButton_Unchecked(object sender, RoutedEventArgs e)
{
_hasBeenToggled = true;
}
You then simply check the value of the field in your other method:
var ToggleButtonControl = (ToggleButton)ControlName; //
if (!_hasBeenToggled) //<--
{
parameterStr = "/////////////";
//MessageBox.Show("This should pop-up only if the user never toggled the button");
}
else
{
//MessageBox.Show("The user toggle or toggle it back");
if (ToggleButtonControl.IsChecked == false)
parameterStr = "لا";
else
parameterStr = "نعم";
}
If you follow the MVVM design pattern, you could just set the _hasBeenToggled in the setter of your source property.
I am new in coding and atm trying to understand events what is an annoying stage but super important I guess. I just made a tic tac toe game and it is working but not really "beautiful" coded. I really have problems in using the events. well I am reading 3 different books, google is my best friend and I guess I red all the StackOverflow posts about events but the bulb in my head is never shining :P so I will give you boys a part of my code and I added some comments for the understanding:
/*I have 9 buttons(3x3) which are the play field */
private void Feld1_Click(object sender, RoutedEventArgs e)
{
// in my game each player have 1 Radiobutton so they check a RButton and then it's their turn
if (Player1RButton.IsChecked == true)
{
// i dont wanted to use "X" or "O" so i chose the colors green and yellow
Feld1.Background = Brushes.Green;
// Feld1G is for example that Player1 (green) is "owning" this
// field/button so i can later check who won the game
Feld1G = 1;
Feld1Y = 0;
}
if (Player2RButton.IsChecked == true)
{
//here is the same thing happening like in the example of green
Feld1.Background = Brushes.Yellow;
Feld1Y = 1;
Feld1G = 0;
}
}
private void Feld2_Click(object sender, RoutedEventArgs e)
{
if (Player1RButton.IsChecked == true)
{
Feld2.Background = Brushes.Green;
Feld2G = 1;
Feld2Y = 0;
}
if (Player2RButton.IsChecked == true)
{
Feld2.Background = Brushes.Yellow;
Feld2Y = 1;
Feld2G = 0;
}
}
here is an example how the ui looks like:tic tac toe exampe
now what I would like to do in my words cause I don't know how to code it:
// I have no idea if this is the right start
public void OnClick (EventArgs e)
{
/* now I guess here have to happen something like this, for example, field9 was clicked and radiobutton2 is checked: know that button9 have been clicked know radiobutton is checked and now brush (this.button?) button/field9 and set Feld9Y=1;
}
*/
I want to make it a bit more clearly here: I want all the functions run from the method above and not in each button event for itself
so my questions:
1. what do I have to do to make this work the way i explained above to make 1 method for all of my buttons
and it would be great if you boys could make a good story why I have to use it this way and how it works so a brainless ape like me can understand the event stuff and the bulb will finally shine bright like a diamond :P
Edit:here is the link for my whole code:
https://codereview.stackexchange.com/questions/164462/c-events-in-a-tic-tac-toe-game
Here is a quick example to get you started. I only implemented changing the background and nothing more.
Below is the xaml. I set up a very simple board with 9 regular buttons and 2 radio buttons. I did not implement anything else.
<Grid x:Name="board">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button Content="Button"/>
<Button Content="Button"
Grid.Column="1" />
<Button Content="Button"
Grid.Column="2"/>
<Button Content="Button"
Grid.Row="1" />
<Button Content="Button"
Grid.Row="1"
Grid.Column="1" />
<Button Content="Button"
Grid.Row="1"
Grid.Column="2" />
<Button Content="Button"
Grid.Row="2" />
<Button Content="Button"
Grid.Row="2"
Grid.Column="1" />
<Button Content="Button"
Grid.Row="2"
Grid.Column="2" />
<RadioButton x:Name="playerOneRadioButton"
IsChecked="True"
Content="Player 1"
Grid.Column="3"
HorizontalAlignment="Left"
Margin="10,10,0,0"
Grid.Row="1"
VerticalAlignment="Top" />
<RadioButton x:Name="playerTwoRadioButton"
Content="Player 2"
Grid.Column="3"
HorizontalAlignment="Left"
Margin="10,30,0,0"
Grid.Row="1"
VerticalAlignment="Top" />
</Grid>
Below is the code behind.
I hooked up each buttons click event to point to the Button_Click method.
In that method I first cast the sender to type Button. I then change the background color of the button to either yellow or green.
public partial class MainWindow: Window
{
public MainWindow( )
{
InitializeComponent( );
// Iterate through all of the child elements
// contained in the Grid control which I named "board".
foreach( var control in board.Children.OfType<Button>( ) )
{
// Hook up the event handler of each button.
control.Click += Button_Click;
}
}
private void Button_Click( object sender, RoutedEventArgs e )
{
// Safe cast the sender to type Button.
var button = sender as Button;
if( button == null ) return;
// Change the background color of the button
// yellow or green based on which radio button
// is checked.
button.Background = playerOneRadioButton.IsChecked.Value ? Brushes.Green : Brushes.Yellow;
}
}
EDIT:
Question 1: The Grid which I have on the design surface is named "board". Children is a property of the Grid control. All child elements (elements that reside inside of the grid, like the buttons) are added to the Children property of the grid control. The Children property is a collection, or you could say a list, of all child elements that reside in the grid control. I loop through each child control in the grid that is of type button.
Question 2: The ?: is called a ternary operator. It is used for writing a conditional statement (an if statement). You can also write it as follows:
if( playerOneRadioButton.IsChecked.Value )
{
button.Background = Brushes.Green;
}
else
{
button.Background = Brushes.Yellow;
}
Question 3: I'm currently casting the object sender to type button using whats called a "safe cast". In other words, if the cast fails (say sender wasn't a button and was some other control instead) then null is returned. I check for this null condition to ensure that the cast was successful. If the button variable is null then the cast was not successful and I want to exit (return) out of that method. No code below the
if(button == null) return;
will execute.
The single method you want to use should look like this:
private void Feld_Click(object sender, RoutedEventArgs e)
{
var currentButton = (Button)sender;
if (Player1RButton.IsChecked == true)
{
currentButton.Background = Brushes.Green;
}
}
Add this as OnClick handler for all the buttons.
From there you can calculate the Feld color whenever you need it, by accessing the Background property in a separate method.
I tried this below code:
XAML Code:
<GridView x:Name="listgrid">
<GridView.ItemTemplate>
<DataTemplate>
<StackPanel Margin="15,15,0,0">
<Image Height="170" Width="170" Source="{Binding}"></Image>
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
Cs code:
for (int i = 1; i < 50; i++)
{
list.Add("ms-appx:///Images/A-aa.jpg");
}
listgrid.ItemsSource = list;
listgrid.ScrollIntoView(listgrid.Items[30]);
I above code to scroll view to my selected item, but it's not showing any changes, i think i used this property in a wrong way any one please help me to scroll to gridview position.
I have replied your same question in MSDN: https://social.msdn.microsoft.com/Forums/windowsapps/en-US/d0a772b3-80b9-4a11-92a9-89963c29a52f/scrollintoview-property-not-working-for-gridview-in-windows-10-universal-app?forum=wpdevelop
You need to have something more to distinguish items, for example, give every image a name since items you bind to GridView are same, ScrollIntoView default find the first one.
And commonly you need to set a height property for the GridView.
For more complex requirements, there is a good thread you can reference:
Windows 10 ScrollIntoView() is not scrolling to the items in the middle of a listview
Try to subscribe on Loaded event and call ScrollIntoView inside event handler:
listgrid.Loaded += Listgrid_Loaded;
....
private void Listgrid_Loaded(object sender, RoutedEventArgs e)
{
listgrid.ScrollIntoView(listgrid.Items[30]);
}
Try this
private void Gridview_Loaded(object sender, RoutedEventArgs e)
{
if (ShellPage.Current.SelectedRecItem != null)
{
this.gridview.SelectedItem = ShellPage.Current.SelectedRecItem;
this.gridview.UpdateLayout();
this.gridview.ScrollIntoView(ShellPage.Current.SelectedRecItem);
}
}
I'm using the Items Page template from the Windows 8.1 Windows Store Apps templates in XAML. The page features a large GridView control with multiple item elements.
I would like to enable the dragging and reordering of items, but only after a user long clicks one of the items (similar to how it's done on the Windows Tablet Start menu and the iOS/Android home screen).
I've tried binding to the Holding event and enabling CanDragItems and CanReorderItems, but the user cannot start dragging the item during the Holding event.
Here's the GridView definition:
<GridView
x:Name="itemGridView"
AutomationProperties.AutomationId="ItemsGridView"
AutomationProperties.Name="Items"
TabIndex="1"
Grid.RowSpan="2"
Padding="116,136,116,46"
ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
SelectionMode="None"
IsSwipeEnabled="False"
IsItemClickEnabled="True"
CanReorderItems="False"
AllowDrop="False"
CanDragItems="False"
ItemClick="itemGridView_ItemClick"
>
With this in the code behind:
void OnHolding(object sender, HoldingRoutedEventArgs e)
{
if( e.HoldingState == Windows.UI.Input.HoldingState.Started)
{
Debug.WriteLine("Drag Start");
itemGridView.CanDragItems = true;
itemGridView.IsSwipeEnabled = true;
itemGridView.CanReorderItems = true;
itemGridView.AllowDrop = true;
}
else
{
Debug.WriteLine("Drag End");
itemGridView.CanDragItems = false;
itemGridView.IsSwipeEnabled = false;
itemGridView.CanReorderItems = false;
itemGridView.AllowDrop = false;
}
}
Thanks!
After much fuss and chasing down events, I was able to get the intended effect on pen, mouse, and touch devices.
The following code is not guaranteed to be the best way to accomplish the long click drag, but it is functioning on my devices with Windows 8.1. I encourage someone to find a better solution, since this one is kind of messy.
Code behind looks like this:
private bool isHolding = false;
private bool canUserDragItem = false;
// If a user moves their pointer outside the item's area or releases their pointer, stop all holding/dragging actions.
private void Grid_StopAllowDrag(object sender, PointerRoutedEventArgs e)
{
canUserDragItem = false;
isHolding = false;
}
// If a user starts dragging an item, check and see if they are holding the item first.
private void itemGridView_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
{
if (!canUserDragItem) e.Cancel = true;
}
private async void Grid_PointerPressed(object sender, PointerRoutedEventArgs e)
{
// Whenever a user presses the pointer inside the item, wait for half a second, then decide if the user is holding the item.
isHolding = true;
await Task.Delay(500); // Wait for some amount of time before allowing them to drag
if (isHolding) // If the user is still holding, allow them to drag the item.
{
canUserDragItem = true; // Allow them to drag now
// TODO: Make it apparent that the user is able to drag the item now.
}
}
And the XAML looks like this:
<GridView
x:Name="itemGridView"
AutomationProperties.AutomationId="ItemsGridView"
AutomationProperties.Name="Items"
TabIndex="1"
Grid.RowSpan="2"
Padding="116,136,116,46"
ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
SelectionMode="None"
IsSwipeEnabled="True" <!-- Enable dragging on touch devices -->
CanReorderItems="True" <!-- Allow users to try to start dragging -->
AllowDrop="True"
CanDragItems="True"
DragItemsStarting="itemGridView_DragItemsStarting" <!-- Stop dragging while not holding -->
>
<GridView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Left" Width="250" Height="250"
<!-- Items must be given these event handlers -->
PointerPressed="Grid_PointerPressed"
PointerReleased="Grid_StopAllowDrag"
PointerCanceled="Grid_StopAllowDrag"
PointerCaptureLost="Grid_StopAllowDrag"
PointerExited="Grid_StopAllowDrag"
>
You need another else case. Your logic looks like this.
If they started doing something. Set properties to true.
While they are still holding the properties will be set to false.
You probably want two separate events. Holding started and Holding stopped. Not just a blanket else there.