WPF TextBox does not lose focus - c#

I knwow there are many other who wrote about this but the suggested solutions don't solve my problem.
I've got a sort of gallery and I need that when the user edits the number specified in the TextBox automatically the image is updated.
Initially I tried with LostFocus event, but it doesn't always fire as explained here.
If I bind the property as suggested here, I have too many events if the number has more than one digit.
Then I tried to do this, but it doesn't work.
This is how my TextBox is defined:
<TextBox Margin="2" Text="{Binding NImageShown}" FontSize="18"
LostFocus="ImageIndex_OnLostFocus"
Name="ImageIndex" Height="40" Width="60"
VerticalAlignment="Center" VerticalContentAlignment="Center"
Focusable="True">
</TextBox>
I implemented the third solution by attaching the window to MouseDown event:
<Window x:Class="...."
.....
MouseDown="Window_MouseDown"....>
private void Window_MouseDown(object sender, MouseButtonEventArgs e)
{
if (ImageIndex.IsFocused)
Keyboard.ClearFocus();
}
With this solution I sawy that ImageIndex.IsFocused remains true even after Keyboard.ClearFocus(): this is the reason why I think that solution does not fix my problem.
Any help is really appreciate!
EDIT
Changes based on the suggestions:
<Grid Grid.Row="2" Grid.Column="2" Name="GridTextbox">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
.....
<StackPanel Grid.Column="2" Orientation="Horizontal"
HorizontalAlignment="Right">
<TextBox Margin="2" Text="{Binding NImageShown}" FontSize="18" LostFocus="ImageIndex_OnLostFocus"
Name="ImageIndex" Height="40" Width="60" VerticalAlignment="Center" VerticalContentAlignment="Center" Focusable="True"></TextBox>
<Label Style="{DynamicResource LabelStyle}" VerticalAlignment="Center"
Content="{Binding NTotalImages}" FontSize="18" Padding="5,0,5,0" Margin="5,5,5,5" />
</StackPanel>
</Grid>
private void Window_MouseDown(object sender, MouseButtonEventArgs e)
{
if (ImageIndex.IsFocused)
{
GridTextbox.Focus();
Keyboard.ClearFocus();
}
}
Even with these changes, LostFocus doesn't fire.
SOLUTION
Change the xaml as suggested in this way and keep the code behind as written before:
<TextBox Margin="2" Text="{Binding NImageShown}" FontSize="18"
LostKeyboardFocus="ImageIndex_OnLostFocus"
KeyDown="ImageIndex_OnLostFocus"
Name="ImageIndex" Height="40" Width="60"
VerticalAlignment="Center" VerticalContentAlignment="Center"
Focusable="True">
</TextBox>

Related

Extended Textbox is behind other elements in WPF

It's the first time i am learning WPF with C#.
So i have a textbox which is extended when i click on a button. The problem is when i extend it,it remains behind my other elements(textboxes etc...)
Here is the xml code for the textbox.
<StackPanel Grid.Column="1" Grid.ColumnSpan="4" Grid.Row="3" Grid.RowSpan="5" Panel.ZIndex="0" Visibility="Collapsed" Name="descriptionPanel" Margin="2,0,0,0" Background="White">
<Border BorderBrush="DarkGray" BorderThickness="1" CornerRadius="5">
<StackPanel Orientation="Horizontal">
<TextBox Name="descriptionTextBoxExtended"
Margin="10,10,10,10"
Style="{StaticResource expandedTextBox}"
Text="{Binding Path=Description, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true, TargetNullValue=''}"
IsReadOnly="{Binding RelativeSource={RelativeSource AncestorLevel=1,AncestorType=Control}, Path=SecurityLevel2ReadOnly, Mode=OneWay}"
/>
<Button Name="descriptionHide" Style="{StaticResource MinusButton}" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,10,10" Click="descriptionHide_Click" />
</StackPanel>
</Border>
</StackPanel>
And here is the C#
private void exDescription_Click(object sender, RoutedEventArgs e)
{
descriptionPanel.Visibility = Visibility.Visible;
}
This is how it looks when i run it before i click the extend button:
And this is how it looks when i extend the textbox:
I want all the highlighted components to be behind the textbox.
You should give us the code of the other elements beside "descriptionPanel", but as mm8 pointed out, it seems that your elements are not in the same Panel.

C# UWP ToggleSwitch in ListView

Suppose you have the ListView below :
<ListView x:Name="ListViewActiveAssets" Margin="10,10,10,10" CanReorderItems="True" AllowDrop="True" CanDragItems="True" SelectionMode="Extended" DragItemsStarting="ListViewActiveAssets_DragItemsStarting" DragItemsCompleted="ListViewActiveAssets_DragItemsCompleted">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Asset">
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="36" />
<ColumnDefinition Width="36" />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition Width="108" />
</Grid.ColumnDefinitions>
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<TextBlock Text="{x:Bind AssetType}" FontFamily="Segoe MDL2 Assets" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<TextBlock Text="{x:Bind Name}" Grid.Column="2" FontSize="18" VerticalAlignment="Center" Padding="0,0,5,0"/>
<TextBlock Text="{x:Bind StartDate}" Grid.Column="3" FontSize="16" VerticalAlignment="Center" Padding="0,0,5,0"/>
<TextBlock Text="{x:Bind EndDate}" Grid.Column="4" FontSize="16" VerticalAlignment="Center" Padding="0,0,5,0"/>
<ToggleSwitch Grid.Column="8" x:Name="ToggleSwitchEnable" IsOn="{x:Bind IsEnabledSwitch}" OnContent="On" OffContent="Off" Padding="5,0" Toggled="ToggleSwitchEnable_Toggled"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
This ListBox can be reordered and this work fine. I simply would like to know why the Toggled event is fired when I reorder an item in ListView ?
Indeed, my Toggled event contains code that refresh the ListView, so when I'am dragging item, the ListView refreshes and the drag&drop fail.
If someone have a suggestion... Thanks in advance!
Try adding a local bool in your class and set it to false in your constructor:
private bool toggling;
public myPage()
{
toggling = false;
}
Then, in your OnToggled method, start by setting toggling to true and then set it back to false at the end of the method.
void ToggleSwitchEnable_Toggled(object sender, EventArgs e)
{
toggling = true;
// Your code
toggling = false;
}
You can then set your refresh method to only execute when toggling is false:
void refresh()
{
if(toggling)
return;
//Your code
}
This will cause the refresh command to be skipped whenever you toggle the switch

WPF listview items fires unlimited MouseEnter and MouseLeave events

I have list view with some items in it, an image with title and description.
I have to implement a functionality to show an hover with an image when user mouseenter in the area of image with in the list item.
Ever thing is working fine but have one problem.
Every time when i hover over any image, hovered image causing blinking underneath there will be unlimited calls of mouseenter and mouseleave events.
I did googling and find SCOTT HANSELMAN's blog post but nothing works for me.
<ListView ItemsSource="{Binding Path=CurrentSlideItems}" Name="listSlides" SelectionChanged="listSlides_SelectionChanged" KeyDown="listSlides_KeyDown" Padding="0" SelectionMode="Multiple" PreviewMouseDoubleClick="listSlides_PreviewMouseDoubleClick" Grid.ColumnSpan="2">
<ListView.ItemTemplate>
<DataTemplate>
<Grid MaxWidth="{Binding Path=ActualWidth,ElementName=listSlides}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.4*"/>
<ColumnDefinition Width="0.6*"/>
</Grid.ColumnDefinitions>
<Border Grid.Column="0" BorderBrush="Black" BorderThickness="1,1,1,1" Margin="0,2">
<Image Source="{Binding Path=Image}" MaxWidth="150" Name="image1" Stretch="Fill" Margin="0" MouseEnter="image1_MouseEnter" MouseLeave="image1_MouseLeave">
</Image>
</Border>
<StackPanel Orientation="Vertical" Grid.Column="1">
<TextBlock FontWeight="Bold" Text="{Binding Path=Title}" Margin="5,4,2,2" TextWrapping="Wrap" TextTrimming="WordEllipsis"/>
<TextBlock Text="{Binding Path=Description}" Margin="5,2,2,2" TextWrapping="Wrap" MaxHeight="80" TextTrimming="CharacterEllipsis" />
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Edit: with events
private void image1_MouseEnter(object sender, MouseEventArgs e)
{
var srcImg = e.Source as System.Windows.Controls.Image;
showPopup(srcImg);
}
private void image1_MouseLeave(object sender, MouseEventArgs e)
{
var pop = (Popup)this.FindResource("popup");
if (!pop.IsMouseCaptured)
{
if (!popupFlag)
{
pop.IsOpen = false;
}
}
}

Checkbox in ItemTemplate

I have a <Checkbox/> in my <GridView.ItemTemplate>. How do I handle the <Checkbox/> as to the element in which it is?
For example, I want to delete item when checkbox checked.
I think should write here. But what?
private void CheckBox_Checked_1(object sender, RoutedEventArgs e)
{
}
Here's My XAML:
<GridView Margin="0,10,0,0"
RelativePanel.AlignHorizontalCenterWithPanel="True"
x:Name="GridColections"
IsItemClickEnabled="True"
SelectionMode="None"
ItemsSource="{x:Bind DS.AllRem, Mode=OneWay}"
ItemClick="GridColections_ItemClick" >
<GridView.ItemTemplate>
<DataTemplate x:DataType="local:GetRem" >
<Grid Margin="-2,0,-6,0" BorderBrush="LightGray" BorderThickness="1" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="40" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<TextBlock TextTrimming="CharacterEllipsis" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Stretch" TextWrapping="Wrap" Text="{x:Bind ReminderName}" Margin="5,5,0,0" FontSize="20"/>
<TextBlock TextTrimming="CharacterEllipsis" Grid.Column="0" Grid.Row="1" Width="600" TextWrapping="Wrap" Text="{x:Bind ReminderDescription}" Margin="5,5,0,0" FontSize="12"/>
<CheckBox Grid.Column="2" Grid.Row="0" Grid.RowSpan="2" VerticalAlignment="Center" Checked="CheckBox_Checked_1"/>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
The problem is that you almost certainly want to be able to use the DataContext in your click handler but you won't get that easily by just having a reference to the CheckBox which will be the sender argument in your callback. Normally what you would do here is create a Command on your item's view model and bind to that and any additional information that you would want to pass in you would pass in through the CheckBox's CommandParameter.
Once you do this you are now operating in your view model with a reference to whatever piece of information that you need through the command parameter (for instance you could set CommandParameter = "{Binding}" to pick up the entire data context which would be the item's view model and that would be accessible from your Command as an argument to it). You should be able to solve your issue this way.

access controls present in data template from code behind

I have the following XAML code..
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Key="DataTemplate1" >
<Border BorderBrush="LightGray" BorderThickness="1" Height="150" Width="500" >
<Grid Width="500" Height="150" Background="White" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="2.5*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image Grid.Column="0" Height="Auto" Width="Auto" Source="/Images/notav.jpg" Margin="0,5,4,4" HorizontalAlignment="Left" />
<TextBlock Text="{Binding PRICE}" TextWrapping="Wrap" Grid.Column="1" Width="350" Foreground="Black" Height="60" Margin="30,85,20,-10"/>
<TextBlock Text="{Binding ITMNAME }" FontSize="22" TextWrapping="Wrap" Grid.Column="1" Name="txtITMNAME" Foreground="DarkBlue" Width="500" Height="130" Margin="30,40,20,-10"/>
<c4f:RoundButton Grid.Column="2" Name="btntick" Click="btntick_Click" Grid.Row="0" FontSize="25" HorizontalAlignment="Right" Background="LightGray" Foreground="DarkGray" Margin="10,20,45,10" />
</Grid>
</Border>
</DataTemplate>
<ListBox Height="Auto" Name="lstbxmanual" ItemTemplate="{StaticResource DataTemplate1 }" Width="475" Margin="4,148,0,5" Background="White" HorizontalAlignment="Left" Grid.RowSpan="2">
</ListBox>
I have to access round button at code behind ,to change its background property...
private void btntick_Click(object sender, RoutedEventArgs e)
{
btntick. //not able to access...
}
I have gone through following stackoverflow questions..
Access DataTemplate controls in code behind
MSDN link
it seems to be not relevant to my requirement..
please help me in this regard...
Solution 1: Use x:Name instead of Name.
Solution 2: Here is the an alternate way too.
You can cast the event sender object:
private void btntick_Click(object sender, RoutedEventArgs e)
{
RoundButton rdbtn = sender as RoundButton;
//rdbtn.BackColor
}
please try, x:Name in place of Name it will be accessible from your code behind file.
<c4f:RoundButton Grid.Column="2" x:Name="btntick" Click="btntick_Click" Grid.Row="0" FontSize="25" HorizontalAlignment="Right" Background="LightGray" Foreground="DarkGray" Margin="10,20,45,10" />
private void btntick_Click(object sender, RoutedEventArgs e)
{
btntick.Foreground = Brushes.Blue;
}
Good Luck.

Categories