I have following ListView
<ListView Name="listAccounts" Width="300" AllowDrop="True" SelectionMode="Single" CanDragItems="True" CanDrag="True" CanReorderItems="True" Background="{ThemeResource myBackground}" DragItemsStarting="listAccounts_DragItemsStarting" Drop="listAccounts_Drop">
and defined my event handlers as
private void listAccounts_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
{
e.Data.SetData("itemIndex", (e.Items[0] as AccountList).Text.ToString());
}
private async void listAccounts_Drop(object sender, DragEventArgs e)
{
string itemIndexString = await e.Data.GetView().GetTextAsync("itemIndex");
}
I don't know what else I can do. I want to realize the movement of the list items in the same list.
I went over to the official Windows 10 samples, looked for the drag-drop sample and trimmed it down (like removing the drag from target to source). Turns out you don't even have to handle any events to make re-ordering in a single ListView work.
<ListView x:Name="TargetListView"
Grid.Row="2" Grid.Column="1" Margin="8,4"
CanReorderItems="True" CanDrag="True" AllowDrop="True"
/>
Check your ObservableCollection after reordering items and you'll notice it's correct. If you want to track the re-ordering, you'll have to check the CollectionChanged event on your ObservableCollection, as there is no event on the ListView to do this.
If you want to support drag & drop accross multilple listviews, I'd say have another look at the sample.
Related
I have a Ribbon with two tabs and one of the tabs contains a listbox, with auto-generated content.
I would like the mouse wheel to scroll through the listbox content and have tried lots of things, but the mouse wheel only ever switches Ribbon tabs.
Below is one solution I have tried where I attempt to release mouse the mouse control from the Ribbon and give it to the ListBox but, so far I have been unsuccessful. Is there a proper way to do this? Am I missing something?
xaml
<Ribbon Name="ribbonMain">
<RibbonTab Header="Home">
<RibbonGroup Header="Employees" Width="200">
<ListBox x:Name="empListBox" ItemsSource="{Binding SelectedEmployees}"
Width="180"
MouseEnter="empListBox_MouseEnter"
MouseLeave="empListBox_MouseLeave">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Path=FirstName}" IsChecked="{Binding IsChecked}"></CheckBox>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</RibbonGroup>
xaml.cs
private void empListBox_MouseEnter(object sender, MouseEventArgs e)
{
if (sender is ListBox)
{
ribbonMain.ReleaseMouseCapture();
((ListBox)sender).CaptureMouse();
}
}
private void empListBox_MouseLeave(object sender, MouseEventArgs e)
{
((ListBox)sender).ReleaseMouseCapture();
ribbonMain.CaptureMouse();
}
I think the problem is that the ListBox itself can't really do anything with the mouse capture. I think it's actually the scroll viewer inside the ListBox template that needs to receive the wheel events.
Try changing your mouse handlers like so:
private void empListBox_MouseEnter(object sender, MouseEventArgs e)
{
Mouse.Capture(empListBox, CaptureMode.SubTree);
}
private void empListBox_MouseLeave(object sender, MouseEventArgs e)
{
empListBox.ReleaseMouseCapture();
}
This will make mouse events visible to the element holding the capture *and* its descendant elements, including the scroll viewer.
When I tab into a ListBox control, the first item gets focused. When I have a label and set the target property to the ListBox (as shown in the code below) and then use the dedicated Alt shortcut then it will focus not the first item but the listbox itself (listbox border becomes dotted). What is the best way to avoid this unwanted behavior? Is there a way to disable focusing on the listbox itself and only allow focusing on the items?
Example code:
<Label Content="_Label" Margin="0,10,0,88" Name="MyLabel" Target="{Binding ElementName=MyListBox}" Height="Auto" />
<ListBox Width="100" Name="MyListBox" Margin="46,0,639,0" />
Behavior:
By setting Target you explicitly asked focus to move to listBox. In case you want to put it on first listBox item, you have to do it manually.
One way would be to hook GotFocus event and set focus to next available item using TravelRequest object which wil put it on first listBox item.
XAML:
<ListBox Width="100" Name="MyListBox" Margin="46,0,639,0"
GotFocus="MyListBox_GotFocus"/>
Code behind:
private void MyListBox_GotFocus(object sender, RoutedEventArgs e)
{
if (e.OriginalSource == sender)
{
TraversalRequest request = new TraversalRequest(FocusNavigationDirection.Next);
MyListBox.MoveFocus(request);
}
}
I have listbox with items from observablecollection.
<ListBox Name="listBoxData"
DataContext="{Binding Source={StaticResource MainWindowViewModelDataSource}}"
ItemTemplate="{DynamicResource BookTemplate}"
ItemsSource="{Binding Books, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SelectedBook, Mode=TwoWay}">
Question is how to wire double click action on selected item?
I do not avoid code behind approach (which is currently empty, all my logic is inside mvvm).
Your final line is a little confusing... to me, it says 'a code behind solution is ok', but then you mention MVVM, so I'm not sure. Either way, here is a simple answer for you. Declare the ListBox:
<ListBox SelectionChanged="ListBox_SelectionChanged" />
And then in the code behind, assuming single selection mode:
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBoxItem listBoxItem = (ListBoxItem)e.AddedItems[0];
listBoxItem.PreviewMouseDoubleClick += ListBoxItem_PreviewMouseDoubleClick;
listBoxItem = (ListBoxItem)e.RemovedItems[0];
listBoxItem.PreviewMouseDoubleClick -= ListBoxItem_PreviewMouseDoubleClick;
}
private void ListBoxItem_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
// Selected item was double clicked
}
If you want the MVVM way, then you can just move the code from the ListBox_SelectionChanged handler to the SelectedBook setter and the ListBoxItem_PreviewMouseDoubleClick handler to the view model. However, it's not such a good idea handling UI events in the view model. It's better to use Attached Properties to handle them for you, but that's another story.
I want to populate a listbox after inputting text into a text box and clicking Submit. Seems simple I know, but I'm new to Data Binding and WPF...
Here's my code so far... I don't know if the XAML is correct, and of course I have nothing in the event code behind... any help would be appreciated.
XAML:
<ListBox ItemsSource="{Binding ElementName=accountaddTextBox, Path=SelectedItem.Content, Mode=OneWay, UpdateSourceTrigger=Explicit}" Height="164" HorizontalAlignment="Left" Margin="12" Name="accountListBox" VerticalAlignment="Top" Width="161" />
Code behind:
private void okBtn_Click(object sender, RoutedEventArgs e)
{
}
Your current binding is telling the ListBox to find an object named accountaddTextBox, and bind to its SelectedItem.Content. I am assuming that accountaddTextBox is a TextBox, and SelectedItem is not a valid property on TextBox, so your binding is invalid.
It would be far better to bind your ListBox to an ObservableCollection<string> that is located in your code-behind or ViewModel, and have your button add a new object to that collection. Since it is an ObservableCollection, the UI will automatically update
For example,
<ListBox ItemsSource="{Binding SomeObservableCollection}" />
private void okBtn_Click(object sender, RoutedEventArgs e)
{
SomeObservableCollection.Add(accountaddTextBox.Text);
}
I am new in this field and am trying to do a drag and drop from scatterview to librarystack, and when drop is executed, an event should be triggered ( after an image is dropped in the librarystack, a message box will be shown). However, I can not find the way to do it..
Below is the code snippets
<Grid>
<!-- Drop 1.jpg to librarystack-->
<s:ScatterView AllowDrop="True">
<Image Source="C:\1.jpg"/>
</s:ScatterView>
<!--Librarystack get the 1.jpg and trigger an event-->
<s:LibraryStack x:Name="myLibraryStack" Drop="myLibraryStack_Drop" Margin="376,0,389,0" Background="Transparent" Height="162" VerticalAlignment="Top" AllowDrop="True">
</s:LibraryStack>
</Grid>
and
public SurfaceWindow1()
{
InitializeComponent();
SurfaceDragDrop.AddDropHandler(myLibraryStack, OnPreviewDrop);
}
private void myLibraryStack_Drop(object sender, SelectionChangedEventArgs e)
{
MessageBox.Show("HALLO");
}
Would appreciate for any guidance
I think that the LibraryStack has to be inside the Scatterview to receive the drop. But I'm not sure. I had the problem myself once and this solved it, if I remember correctly.