I'm having a little trouble with the WPF ListView and couldn't find any answer to this. I'm having a simple ListView in a WPF application with a few items in it. I have also attached a GotFocus event-handler on the GotFocus event. It seems that for every selection I do on the ListView also the GotFocus event is fired
xaml-code
<Window x:Class="WpfApplication4.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">
<Grid>
<ListView x:Name="MS" GotFocus="MS_GotFocus"></ListView>
</Grid>
cs-code
using System;
using System.Collections.Generic;
using System.Windows;
namespace WpfApplication4
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
List<string> test = new List<string>();
test.Add("Item 1");
test.Add("Item 2");
MS.ItemsSource = test;
}
private void MS_GotFocus(object sender, RoutedEventArgs e)
{
Console.WriteLine("Focus");
}
}
}
Has someone also experienced this problem?
Thanks
Martin
Related
ok Im not sure if this issue is related to the library or me being still being new to WPF .but , I'm using the dragablz library and I am trying to re-add a tab after tearing it then closing that specfic window. However , I cant seem to find all the TabItem when ever I try to search for it in the grid of the current winodw I get nothing , this what I treid.
<Window x:Class="TeheMan8_Editor.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"
xmlns:local="clr-namespace:TeheMan8_Editor"
xmlns:dragablz="http://dragablz.net/winfx/xaml/dragablz"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<dragablz:TabablzControl Name="tabHub" AllowDrop="True" Grid.ColumnSpan="2">
<dragablz:TabablzControl.InterTabController>
<dragablz:InterTabController />
</dragablz:TabablzControl.InterTabController>
<TabItem Name="mainTab" Header="Tab No. 1" IsSelected="True">
<Button Click="Button_Click">Open FileButton</Button>
</TabItem>
</dragablz:TabablzControl>
</Grid>
</Window>
CSharp Code:
using DiscUtils.Iso9660;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
namespace TeheMan8_Editor
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var items = this.grid.Children.OfType<TabItem>(); //returns Empty
}
}
}
never mind I figured it out , the TabablzControl Object has a OfType function for the "Items.SouceCollection" property
I'm trying to move my PNG across my canvas with C# in a WPF application.
I've tried using extra directives. I've used every keyword I can think of. I've created event handlers and it seems the event isn't firing correctly. And my image fails to move.
namespace Pazulu {
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
}
private void Image_KeyDown(object sender, KeyEventArgs e) {
var alpha = Key.Space;
if (e.Key == alpha)
Canvas.SetLeft(pazulu, 300);
}
}
}
No error message. The expected result should be, at least, to capture an event while debugging, but no event is detected. And my image sits dormant.
You probably need to subscribe to the KeyDown event on the Window. Something like:
<Window x:Class="WpfApp3.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"
xmlns:local="clr-namespace:WpfApp3"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" KeyDown="MainWindow_OnKeyDown">
<Canvas>
<Button Name="MyButton" Canvas.Right="10">Test</Button>
</Canvas>
</Window>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace WpfApp3
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void MainWindow_OnKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Right)
{
//Whatever, just an example
Canvas.SetRight(MyButton, Canvas.GetRight(MyButton) + 5);
}
}
}
}
I have a simple C# WPF application looking like this:
I'm adding Item2 programmatically, and I wonder why the Loaded event is fired both shortly after it has been added to the TabControl and then again when I open it.
The code for my MainWindow.xaml looks as follows:
<Window x:Class="WpfApplication1.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"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TabControl Name="MyTabControl" >
<TabItem Name="Item1" Header="Item1">
<local:Control1 />
</TabItem>
</TabControl>
</Grid>
</Window>
And its code-behind is:
using System.Windows;
using System.Windows.Controls;
namespace WpfApplication1
{
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
{
var item = new TabItem
{
Content = new Control2(),
Header = "Item2"
};
MyTabControl.Items.Add(item);
}
}
}
As you can see, I have one control called Control1 and another called Control2. They are defined with the following MyControl.xaml file:
<UserControl x:Class="WpfApplication1.MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
</Grid>
</UserControl>
And the following code-behind MyControl.xaml.cs:
using System.Diagnostics;
namespace WpfApplication1
{
public abstract partial class MyControl
{
protected abstract string MyName { get; }
protected MyControl()
{
InitializeComponent();
Loaded += (sender, args) => Debug.Print("Loaded {0}", MyName);
Unloaded += (sender, args) => Debug.Print("Unloaded {0}", MyName);
}
}
public class Control1 : MyControl
{
protected override string MyName => "Control1";
}
public class Control2 : MyControl
{
protected override string MyName => "Control2";
}
}
When I open the application, I get the following console output:
Loaded Control1
Loaded Control2
And when I switch to Item2:
Unloaded Control1
Loaded Control2
And back to Item1:
Unloaded Control2
Loaded Control1
The latter two make sense; when I navigate from a control it gets unloaded while the new control gets loaded.
However, I don't understand why Control2 is loaded initially, before it has been shown. This causes Control2 to receive two Loaded events in a row, before it gets an Unloaded event.
When we add Tab Items explicitly, each tab item is loaded and initialized immediately containing everything.(Please refer to this topic for more details Lazy loading WPF tab content)
I have a WPF application where tooltip is bound to a viewmodel, and all is great when I hover over my control and wait for the tooltip.
To support mouseless devices, I would like to show the same tooltip, when "clicking" my control.
If I implement a MouseDown handler that sets the tooltip's IsOpen = true, the tooltip is shown, but binding has not been evaluated, unless I hover and wait first.
XAML:
<Window x:Class="TooltipApplication.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"
xmlns:local="clr-namespace:TooltipApplication"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Image Source="http://www.brockmann-consult.de/beam/doc/help/visat/images/icons/Help22.png" MouseDown="Image_MouseDown" Stretch="None" MouseLeave="Image_MouseLeave">
<Image.ToolTip>
<ToolTip>
<TextBlock Text="{Binding Hint}"/>
</ToolTip>
</Image.ToolTip>
</Image>
</Grid>
</Window>
Code behind:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace TooltipApplication
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
public string Hint { get { return "This is my hint"; } }
private void Image_MouseDown(object sender, MouseButtonEventArgs e)
{
var tooltip = (sender as FrameworkElement).ToolTip;
if (tooltip is ToolTip)
((ToolTip)tooltip).IsOpen = true;
}
private void Image_MouseLeave(object sender, MouseEventArgs e)
{
var tooltip = (sender as FrameworkElement).ToolTip;
if (tooltip is ToolTip)
((ToolTip)tooltip).IsOpen = false;
}
}
}
Using the code above, click the image before the tooltip timer elapses, or run it on a touch device.
Placing a breakpoint in the Hint getter also proves, that it is not called unless you wait for the tooltip timer.
How can I force the tooltip to evaluate its binding, and then show?
I have a MainWindow that contains multiple views using MVVM. In fact the MainWindow holds only a list of Models and each time a Model is added it creates a View (here a UserControl) and associates the DataContext (Model) to the View. Each view is put into a separate TabItem in a TabControl.
The Model itself has a CommandBindingsCollection and assigns this command bindings to the View. This means that for example F10 is available multiple times, but should only the active View should react on F10.
But, F10 does not work at all. Only if I assign the CommandBinding to the MainWindow it works, but this makes the View dependent on the UserControl and this is not what I want, since I wnat to create the View as independent as possible from the MainWindow.
The only solution I have is to make this dynamically intercepting the change of the current TabItem and add/remove the commands for the active View. Currently everything works without code, but then I have to write code for it.
Attached is a code of the MainWindow:
<Window x:Class="WpfApplication3.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"
xmlns:local="clr-namespace:WpfApplication3"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
</Window>
using System.Windows;
namespace WpfApplication3
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
PluginControl aControl = new PluginControl();
Content = aControl;
}
}
}
and the code of the UserControl:
<UserControl x:Class="WpfApplication3.PluginControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApplication3"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" Background="White">
<StackPanel>
<Button Command="{Binding myCommand}" Content="PushMe" Focusable="False"/>
<Label Content="Nothing pressed" Name="myLabel"/>
</StackPanel>
</UserControl>
using System;
using System.Windows.Controls;
using System.Windows.Input;
namespace WpfApplication3
{
/// <summary>
/// Interaction logic for PluginControl.xaml
/// </summary>
public partial class PluginControl : UserControl
{
public RoutedCommand myCommand
{
get;
private set;
}
public PluginControl()
{
InitializeComponent();
DataContext = this;
myCommand = new RoutedCommand();
myCommand.InputGestures.Add(new KeyGesture(Key.F10));
CommandBindings.Add(new CommandBinding(myCommand, myCommandHandler));
}
private void myCommandHandler(object sender, ExecutedRoutedEventArgs executed)
{
myLabel.Content = DateTime.Now.ToString();
}
}
}
As you see I have set the Button to Focusable false, since I want to have the command working in general, not only when the button is focused. I'm I missing something or thinking in a wrong direction, that making adding a CommandBinding does not implicitly mean that the command does work without binding it?
Adding the Command to the MainWindow itself works.
Any help?