ListView DragDrop doesnt work on new project in VS2013 - wpf

This is a really strange problem, I have a listview that I want to drop files onto, I know how to get the file info etc, and bizarrely I actually had it working fine, but then it seemed to just stop.
I have tried creating a new project with just a listview object, allowdrop=true, dragenter/drop events created, dragenter contains e.handled=true and e.effects = effects.none.
but the events just don't fire, I have a project that was created on an earlier version of VS, and this works fine !!
here is the xmal
<Window x:Name="mainWin" x:Class="droptest.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">
<Window.Resources>
<Style x:Key="ColumnHeaders" TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="Visibility" Value="Collapsed"/>
</Style>
</Window.Resources>
<Grid>
<ListView x:Name="ImageList" AllowDrop="True" HorizontalAlignment="Left" Height="204" Margin="65,69,0,0" VerticalAlignment="Top" Width="374" DragEnter="ImageList_DragEnter" Drop="ImageList_Drop" DragOver="ImageList_DragOver" DragLeave="ImageList_DragLeave">
<ListView.View>
<GridView ColumnHeaderContainerStyle="{StaticResource ColumnHeaders}">
<GridViewColumn/>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
and here is the code
namespace droptest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void ImageList_DragEnter(object sender, DragEventArgs e)
{
e.Handled = true;
e.Effects = DragDropEffects.None;
}
private void ImageList_Drop(object sender, DragEventArgs e)
{
}
private void ImageList_PreviewDragOver(object sender, DragEventArgs e)
{
e.Handled = true;
e.Effects = DragDropEffects.None;
}
private void ImageList_PreviewDrop(object sender, DragEventArgs e)
{
}
private void ImageList_DragOver(object sender, DragEventArgs e)
{
e.Handled = true;
e.Effects = DragDropEffects.None;
}
private void ImageList_DragLeave(object sender, DragEventArgs e)
{
e.Handled = true;
e.Effects = DragDropEffects.None;
}
}
}
I don't think I am doing anything wrong, in fact I am sure I aren't, as I had it working..
any pointers would be much appreciated.

Related

Input gesture doesn't work wpf

Why doesn't my input gesture work in the following?
public class CustomRoutedUICommand : RoutedUICommand
{
private static RoutedUICommand _doSomethingCommand = null;
static CustomRoutedUICommand()
{
InputGestureCollection myInputs = new InputGestureCollection();
myInputs.Add(new KeyGesture(Key.G, ModifierKeys.Control | ModifierKeys.Shift));
_doSomethingCommand = new RoutedUICommand("DoSomething", "DoSomething", typeof(CustomRoutedUICommand), myInputs);
}
public static RoutedUICommand DoSomethingCommand { get { return _doSomethingCommand; } }
}
<Button Height="23" HorizontalAlignment="Left"
Command="{x:Static Control:CustomRoutedUICommand.DoSomethingCommand}"
CommandManager.CanExecute="Command_CanExecute" CommandManager.Executed="Command_Executed"
Content="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Command.Text}"
Margin="12,54,0,0" Name="Command" VerticalAlignment="Top" Width="Auto" Padding="2"/>
private void Command_Executed(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("Hii");
}
In this case, the Command to work, need to have been an element logical focus, otherwise it will not work. You can specify KeyGesture a XAML way:
<Button Height="23" Content="Test" Name="Command" VerticalAlignment="Top"
Command="{x:Static Control:CustomRoutedUICommand.DoSomethingCommand}"
CommandManager.Executed="Command_Executed"
CommandManager.CanExecute="Command_CanExecute">
<Button.InputBindings>
<KeyBinding Command="{x:Static Control:CustomRoutedUICommand.DoSomethingCommand}" Gesture="CTRL+G" />
</Button.InputBindings>
</Button>
It works when the focus will be, it can be specified as follows:
Command.Focus();
To make your case to work, you need to use CommandBindings like this:
XAML
<Window x:Class="InputGestureHelp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Control="clr-namespace:InputGestureHelp"
WindowStartupLocation="CenterScreen"
ContentRendered="Window_ContentRendered"
Title="MainWindow" Height="350" Width="525">
<Window.CommandBindings>
<CommandBinding Command="{x:Static Control:CustomRoutedUICommand.DoSomethingCommand}"
Executed="Command_Executed" CanExecute="Command_CanExecute" />
</Window.CommandBindings>
<Grid>
<Button Height="23" Content="Test" Name="TestButton"
VerticalAlignment="Top"
Command="{x:Static Control:CustomRoutedUICommand.DoSomethingCommand}" />
</Grid>
</Window>
Code behind
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Command_Executed(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("Hii");
}
private void Command_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private void Window_ContentRendered(object sender, EventArgs e)
{
TestButton.Focus();
}
}
public class CustomRoutedUICommand : RoutedUICommand
{
private static RoutedUICommand _doSomethingCommand;
static CustomRoutedUICommand()
{
InputGestureCollection myInputs = new InputGestureCollection();
myInputs.Add(new KeyGesture(Key.G, ModifierKeys.Control, "Ctrl + G"));
_doSomethingCommand = new RoutedUICommand("DoSomething", "DoSomething", typeof(CustomRoutedUICommand), myInputs);
}
public static RoutedUICommand DoSomethingCommand
{
get
{
return _doSomethingCommand;
}
}
}

WPF: How to make textblock fire key event?

TextBlock has KeyDown and KeyUp event, but it's never fired. Is there a way to make it happen? I just need to detect if any key is pressed.
First of all you will need to set the Focusable Property of your TextBlock to True, This will allow you to Tab to the Item but not Click to select it, but if you handle the MouseDown Event you can manualy set Focus to your TextBlock.
MainWindow.xaml
<Window x:Class="WpfApplication1.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 >
<TextBlock Name="tb1" Height="30" Width ="100" IsEnabled="True" Focusable="True" KeyDown="tb1_KeyDown" MouseDown="tb1_MouseDown">Hello World</TextBlock>
</Grid>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void tb1_KeyDown(object sender, KeyEventArgs e)
{
tb1.Background = Brushes.Blue;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
tb1.Focus();
}
private void tb1_MouseDown(object sender, MouseButtonEventArgs e)
{
tb1.Focus();
}
}

Forcing a tri-state checkbox to not move to indeterminate state

I'm working in WPF and i have an interesting requirement.
I need my checkboxes to be ThreeState, so if only some of the child elements are selected it shows as indeterminate. But when a use clicks it, i want it to select either true or false.
Here is a story to represent my requirements:
item - indeterminate
subItem - checked
subItem - unchecked
subItem - checked
When a user clicks item, the checkbox should alternate between checked and unchecked. The user should never be able to select 'indeterminate' as a state. Is this possible?
XAML:
<CheckBox IsThreeState="True" IsChecked="{x:Null}" Click="CheckBox_Clicked" />
Code-behind:
private void CheckBox_Clicked(object sender, RoutedEventArgs e)
{
var cb = e.Source as CheckBox;
if (!cb.IsChecked.HasValue)
cb.IsChecked = false;
}
If you don't like the code-behind solution, then you could sub-class your own control like in the solution for this question.
It's much easier if you use Binding with your CheckBox.
XAML:
<Window x:Class="WpfApplication39Checkbox.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>
<CheckBox Content="CheckBox" HorizontalAlignment="Left" Margin="128,95,0,0" VerticalAlignment="Top" IsThreeState="False" IsChecked="{Binding CheckState}"/>
<Button Content="Button" HorizontalAlignment="Left" Margin="46,241,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
<Button Content="Button" HorizontalAlignment="Left" Margin="139,241,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>
<Button Content="Button" HorizontalAlignment="Left" Margin="235,241,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_2"/>
</Grid>
</Window>
Code-behind:
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
namespace WpfApplication39Checkbox
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
private bool? checkState;
public bool? CheckState
{
get { return checkState; }
set
{
checkState = value;
OnPropertyChanged("CheckState");
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
CheckState = false;
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
CheckState = true;
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
CheckState = null;
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
You see the point? You set the CheckBox to IsThreeState="False" but set the third state from CodeBehind and the CheckBox behaves as expected.

How to close popup in silverlight?

I have ListBox. when i click on ListBox item I have to show item information in popup But it does not close after clicking out side. I am creating popup in itemsselected event. how to handle popup close?
One approach is to create a canvas with a transparent background that you make visible at the same time as opening the Popup and attaching to is Mouse down event to closed the popup. Like this:-
Xaml:-
<Grid x:Name="LayoutRoot" Background="White" >
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Popup x:Name="MyPopup" Closed="MyPopup_Closed" HorizontalOffset="100" VerticalOffset="100" Opened="Popup_Opened">
<ListBox x:Name="PopupChild" MaxHeight="300" LostFocus="PopupChild_LostFocus">
<sys:String>Hello World</sys:String>
</ListBox>
</Popup>
<Button Content="Open Popup" Grid.Row="1" Click="Button_Click" />
<Canvas x:Name="PopupOpen" Visibility="Collapsed" Background="Transparent" Grid.RowSpan="2" MouseLeftButtonDown="PopupOpen_MouseLeftButtonDown" />
</Grid>
Code:-
private void Button_Click(object sender, RoutedEventArgs e)
{
MyPopup.IsOpen = true;
}
private void Popup_Opened(object sender, EventArgs e)
{
PopupOpen.Visibility = Visibility.Visible;
}
private void PopupChild_LostFocus(object sender, RoutedEventArgs e)
{
MyPopup.IsOpen = false;
}
private void PopupOpen_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
MyPopup.IsOpen = false;
}
private void MyPopup_Closed(object sender, EventArgs e)
{
PopupOpen.Visibility = Visibility.Collapsed;
}
Note that its important that if your popup contains a control that can receive the focus that you also handle LostFocus.
This is similar to a question that I had. Take a look at How to dismiss a popup in Silverlight when clicking outside of the control?. I posted in my solution an extension method that's been very helpful in making popups close when clicking outside of them.
I'm not quite sure what you mean by "clicking out side" because popups act in a modal way.
You should set up your popup window as a ChildWindow. Then you can handle the Closed event.
Here's a very simple sample that shows a selected string from a listbox in a main window.
First the main window:
<UserControl x:Class="PopupTest.MainPage"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel Orientation="Vertical">
<ListBox x:Name="SomeList" Width="100" Height="100" />
<TextBlock x:Name="DialogResult" Width="100" />
</StackPanel>
</Grid>
In the codebehind, the popup is triggered when the list selection changes. Simply set up a Closed handler. In this example, I simply put the chosen list item into a textblock, then upon closing the popup, I just put the dialog result in a textblock on the main window (to show if the user pushed ok or cancel).
public MainPage()
{
InitializeComponent();
SomeList.SelectionChanged += new SelectionChangedEventHandler(SomeList_SelectionChanged);
SomeList.Items.Add("one");
SomeList.Items.Add("two");
SomeList.Items.Add("three");
}
void SomeList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var popup = new SomePopup();
popup.Closed += new EventHandler(popup_Closed);
popup.ChosenItem.Text = (string)SomeList.SelectedItem;
DialogResult.Text = "";
popup.Show();
}
void popup_Closed(object sender, EventArgs e)
{
var popup = sender as SomePopup;
if (popup.DialogResult == true)
DialogResult.Text = "Ok";
else
DialogResult.Text = "Cancel";
}
The popup closes when the user pushes Ok or Cancel, because the DialogResult value is set in the popup's code-behind:
private void OKButton_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = true;
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = false;
}

How to bind a WPF control to the code behind?

I have this XAML:
<Window x:Class="WpfBindToCodeBehind.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300"
Loaded="Window_Loaded">
<StackPanel Orientation="Vertical">
<Button Name="ToggleExpand" Click="ToggleExpand_Click">Toggle Expander</Button>
<Expander Name="Expander"
Header="Don't click me, click the button!"
IsExpanded="{Binding RelativeSource={RelativeSource Self},Path=MayExpand}">
<TextBlock Text="{Binding}"/>
</Expander>
</StackPanel>
</Window>
This is the code behind:
public partial class Window1 : Window,INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public Window1()
{
InitializeComponent();
}
private void ToggleExpand_Click(object sender, RoutedEventArgs e)
{
MayExpand = !mayExpand;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Expander.DataContext = "Show me";
}
private bool mayExpand;
public bool MayExpand
{
get { return mayExpand; }
set
{
mayExpand = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("MayExpand"));
}
}
}
The Binding expression for the IsExpanded property is not working. This code is a simplification, in reality the expander's binding is already set through the datacontent of a parent control.
How can I bind the IsExpanded property to a property of the code behind?
Can I bind it to the result of a method in the code behind?
The source for the binding is a RelativeSource.Self. That means the source is the Expander rather than the Window. Something like this will work:
IsExpanded="{Binding MayExpand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}"
You could also use a name to simplify things:
<Window x:Name="_root">
<Expander IsExpanded="{Binding MayExpand, ElementName=_root}"/>

Resources