Issue with Visibility setting of a control inside a group box WPF - c#

I have my groupbox defined inside a window as follows
<ScrollViewer>
<Grid Name="gridMain">
<GroupBox x:Name="grp" Header="Group" Margin="0,71,0,0">
<Grid Margin="0,69,0,0" x:Name="gridmain">
<CheckBox x:Name="ChkShow" Content="Hide Controls" IsChecked="True" Checked="ChkShow_Checked" Unchecked="ChkShow_Unchecked" Margin="27,52,76,38"></CheckBox>
<Label x:Name="lblUsername" Content="Username" Margin="21,10,107,68" Visibility="Hidden"></Label>
</Grid>
</GroupBox>
</Grid>
</ScrollViewer>
This is my code to show/hide the control
private void ChkShow_Unchecked(object sender, RoutedEventArgs e)
{
lblUsername.Visibility = Visibility.Hidden;
}
private void ChkShow_Unchecked(object sender, RoutedEventArgs e)
{
lblUsername.Visibility = Visibility.Visible;
}
But I am unable to find the control it is getting as null so how can I over come this issue

It's all about order.
The CheckBox is created first. The event handlers are attached and the value is set to True. The event handler fires and tries to call the not-yet-created Label. Hence the Label is having the value null.
If you move the label to above the CheckBox it does work. It will also work if you would attach the event handlers later on, for example in the OnLoad method.

I faced a same issue.
Actually checkbox event fire before label control initialize.
So you need to check first control is initialized first, means control not equal to null.
Or you can directly set visibility using binding(need bool to visibility converter) or you can set visibility using data trigger.
<Label x:Name="lblUsername" Content="Username" Margin="21,10,107,68" Visibility="{Binding path=IsChecked, ElementName=ChkShow, Converter={StaticResource converter}}"></Label>
Here is link for bool to visible converter http://wpftutorial.net/ValueConverters.html

Related

UWP Pivot control, how to set focus to first control within PivotItem

I have a Pivot control that uses an ItemsSource to bind to a list of ViewModel instances. I assign a custom ItemTemplateSelector to map between ViewModel types and DataTemplate definitions. This all works fine and the correct display is created for each ViewModel based on the associated DataTemplate. Something like this...
<Pivot ItemsSource="{x:Bind ViewModels}"
ItemTemplateSelector="{StaticResource ViewModelSelector}"
SelectedItem="{x:Bind SelectedViewModel, Mode=TwoWay}"/>
The problem is that I want to automatically set focus to a control within each page when that page is first shown. They are typically data entry forms and so the user currently has to select the first control to start entering data. It would be better if first showing a page automatically then set focus to a control on that page.
Any ideas?
You could bind a method to the TextBox when it's loaded.
For example:
<Pivot.ItemTemplate>
<DataTemplate x:DataType="local:Test">
<TextBox Text="{x:Bind Content}" Height="50" Loaded="{x:Bind TextBox_Loaded}">
</TextBox>
</DataTemplate>
</Pivot.ItemTemplate>
public void TextBox_Loaded(object sender, RoutedEventArgs e)
{
TextBox textBox = sender as TextBox;
if (textBox != null)
{
textBox.Focus(FocusState.Programmatic);
}
}

How to determine which child element of a ListView Item was clicked?

I'm developing a windows phone 8.1 app in XAML and C#. I have a ListView getting its Items from a bound list and displaying them through a DataTemplate. Now, in this DataTemplate there are multiple child elements, and when the user taps on an item in the list, I want to be able to determine what child element he actually touched. Depending on that, the app should either expand a view with more details inside the Item, or navigate to another page.
The ItemClick event handler of the ListView is ListView_ItemClick(object sender, ItemClickEventArgs e), and I thought e.OriginalSource would maybe give me the answer, but this just gave me the clicked ListItem.
I have yet to try if encapsulating the children with buttons and intercepting their click events would work, but I'm happy to try any alternative there might be for this.
I just found the solution myself. I set the ListView to SelectionMode="None" and IsItemClickEnabled="False", and then I added Tapped handlers for the individual child elements. Works just as I wanted.
I've got a TextBlock and an Image in one ListViewItem and have just used the Image_PointerPressed event. Doing that also fires the ItemClick event for the ListView so I disable it first, do the stuff I want, then re-enable the ItemClick event so that still fires when the TextBlock is pressed.
Code behind:
private async void imgDone_PointerPressed(object sender, PointerRoutedEventArgs e)
{
// disable click event so it won't fire as well
lvwCouncils.IsItemClickEnabled = false;
// do stuff
MessageDialog m = new MessageDialog("User Details");
await m.ShowAsync();
// Re-enable the click event
lvwCouncils.IsItemClickEnabled = true;
}
Xaml:
<ListView x:Name="lvwCouncils" ItemClick="lvwCouncils_ItemClicked" IsItemClickEnabled="true" >
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock
Grid.Column="1"
Text="{Binding council_name}"
FontSize="24"
Margin="10,10,30,10"
/>
<Border Height="20" Width="20" Margin="10,10,0,10" >
<Image x:Name="imgDone"
Source="Assets/user_earth.png" Stretch="UniformToFill" PointerPressed="imgDone_PointerPressed"/>
</Border>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Use the SelectionChanged event.
Cast the sender object to ListView type and then retrieve the item from the SelectedItem property.
Similar question here but for a different control :
Get the index of the selected item in longlistselector

How to have a ListBox child item event not call parent event?

Problem
When I click on a ListView item, it calls the "Tapped" event to navigate to another page. I have an Up Vote event within the ItemTemplate and when they call that specific event, I DO NOT want to call the ListView's tapped event. Any idea how I might do that?
ListView XAML:
Parent event, "listboxFeedbackItem_Tapped", occurs anytime any part of the listview is clicked
<Grid x:Name="gridMainData" Grid.Row="2">
<ProgressBar x:Name="prgBar" IsIndeterminate="True" VerticalAlignment="Top" Visibility="{Binding Path=FeedbackVM.IsLoading, Mode=TwoWay}"/>
<ListView ItemTemplate="{StaticResource FeedbackTemplate}" ItemsSource="{Binding FeedbackVM.FeedbackCollection}" Tapped="listboxFeedbackItem_Tapped"/>
</Grid>
ItemTemplate Xaml:
Event "UpVoteItem_Tap" should not trigger "listboxFeedbackItem_Tapped"
<DataTemplate x:Key="FeedbackTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Margin="0,0,30,0" Text="{Binding UpVotes}" Tapped="UpVoteItem_Tap"/>
</StackPanel>
</DataTemplate>
Perhaps there's a method in C# to prevent subsequent events from occurring?
Thanks, I'm still trying to wrap my head around XAML.
When you receive the UpVote tapped event, you can tell it not to pass the event to the parent listview by setting e.Handled=true:
void UpVoteItem_Tap(object sender, TappedRoutedEventArgs e)
{
// Processing here
...
// don't send event to parent
e.Handled = true;
}

In Windows phone,How to change checkbox state after questioning user?

In my app,there is a need to do this
At start,the checkbox is unchecked
user tap,and then pop up a messagebox as a alarm to make sure user indeed want to do it(At the moment the checkmark is still collapse)
If user click "Yes,I want to do it",then checkmark is visible and now it is checked
vice versa
I found that,when I tap the checkbox,Checked event is always triggering
and
the checkmark is always turn to "checked" state
How to solve the problem???
Any advice would be great,Thanks!!!
Just a trick is needed. Sharing a sample with you.
overlap a transparent background grid over your checkbox with a transparent background like this.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<Grid>
<CheckBox Name="cb" Content="cb" Checked="CheckBox_Checked_1"/>
<!--Grid that overlaps the checkbox-->
<Grid Background="Transparent" Tap="Grid_Tap_1"/>
</Grid>
</StackPanel>
</Grid>
This overlapping wont call any checkbox event even if you tap on it
now in code of the event
private void Grid_Tap_1(object sender, GestureEventArgs e)
{
if(MessageBox.Show("Message")==MessageBoxResult.Ok)
{
cb.IsChecked=True;
}
}
Instead of Tap Event, Try Checked and Unchecked Events of the checkbox.
Note: You can track the checked status in "Checked" and "UnChecked" events of the Check Box using IsChecked Property and write your code in appropriate events.
After Asking confirmation to user.
If the user clicks "Yes" , set chkBox.IsChecked=true;
else
If the user clicks "No", set chkBox.IsChecked=false;
I think there is no way to stop checkbox default behaviors. So you can create a custom control with a image and a textbolck inside a stack panel. You should use pair of images for "Image" Control Source one for unchecked and another for checked.
//At start,the checkbox is unchecked
<StackPanel x:Name="panelCheckBox" Tap="panelCheckBox_Tap_1" Orientation="Horizontal">
<Image Source="UncheckImageSourc" x:Name="ImgeCheckBox"/>
<TextBlock Text="CheckBox Content"/>
</StackPanel>
In Code Behind
bool IsChecked=false;
private void panelCheckBox_Tap_1(object sender, System.Windows.Input.GestureEventArgs e)
{
//If user click "Yes,I want to do it",then checkmark is visible and now it is checked
if(!IsChecked)
{
IsChecked =true;
ImgeCheckBox.Source = "CheckImageSource";
}
else
{
IsChecked =false;
ImgeCheckBox.Source = "UncheckImageSourc";
}
}

Child Expanders raising Parent Expander's Expanded and Collapsed Events?

For some reason, child Expanders (placed in a StackPanel inside of another Expander), when collapsed or expanded, cause the parent Expander to raise its Expanded or Collapsed events.
Anyone know why this is or how I can change it? I'm only interested in the parent's events.
Here is some test XAML:
<Expander Header="Outer" Expanded="Expander_Expanded" Collapsed="Expander_Collapsed">
<StackPanel>
<Expander Header="Inner1">
<Canvas Height="100" Width="100" Background="Blue" />
</Expander>
<Expander Header="Inner2">
<Canvas Height="100" Width="100" Background="Red" />
</Expander>
</StackPanel>
</Expander>
and here is the code-behind:
private void Expander_Expanded(object sender, RoutedEventArgs e)
{
MessageBox.Show("expanded");
}
private void Expander_Collapsed(object sender, RoutedEventArgs e)
{
MessageBox.Show("collapsed");
}
When you run this, if you expand the parent, you get an "expanded" messagebox, as you'd expect. But when you then expand one of the children, you get the messagebox again.
The documentation for the Expanded event says:
The Expanded event occurs when the IsExpanded property changes from false to true
But clearly the IsExpanded property isn't changing on the parent Expander.
Why is this happening, any ideas?
Those events are routed and bubble up in the tree, if you want to prevent the parents from handling the event and thus reacting to it, set e.Handled to true in the child expander's event handler.
Edit: Instead of preventing the event from being raised you also could just restrict the code-execution in the handler to the case when the actual expander where the handler is attached raised the event. You can do this by wrapping everything in an if-block which executes if sender == e.OriginalSource.
(Woo, 10k...)

Categories

Resources