I have a GridView and need to set width elements to Stretch as it's content, for now my Gridview looks like this image
I want something like this:
I think something like change ItemsTemplate to an StackPanel, but some samples found on the web are not enough clear for me.
How can I do to change The ItemsTemplate to get the behavior I want?
or
There is another XAML control that allow me to get this behavior?
Note: I'm using VS 2015, performing a UWP app.
check out this:
<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" Loaded="Window_Loaded">
<Window.Resources>
<DataTemplate x:Key="myTemplate">
<StackPanel>
<TextBlock Text="{Binding}"></TextBlock>
</StackPanel>
</DataTemplate>
</Window.Resources>
<ItemsControl ItemTemplate="{StaticResource myTemplate}" ItemsSource="{Binding List}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Window>
In code behind I have this to simulate:
using System.Collections.Generic;
using System.Windows;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
this.List = new List<string> { "Quien", "vie", "ne", "en", "su", "nom", "bre" };
InitializeComponent();
this.DataContext = this;
}
public List<string> List { get; set; }
private void Window_Loaded(object sender, RoutedEventArgs e)
{
}
}
}
Related
I'm trying to wrap my head around ReactiveUI. Most of it makes some degree of sense if you don't look at it too closely, but when I try to set up a TabControl everything explodes in my face.
I have a TabControl on my Window. I want to be able to add multiple different types of tabs to it dynamically at runtime based on different user actions. This answer explains a standard WPF way to do that, and it almost works, but since it's not ReactiveUI, anytime I try to open a tab with a Reactive view on it, everything blows up because the ViewModel dependency property hasn't been bound.
XAML:
<Window.Resources>
<DataTemplate DataType="{x:Type vm:MyTabViewModel}">
<views:MyTabEditor/>
</DataTemplate>
</Window.Resources>
...
<TabControl Name="Multitab" Grid.Column="2" ItemsSource="{Binding Tabs}">
<TabControl.ItemContainerStyle>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Header" Value="{Binding Name}" />
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
ViewModel:
public ObservableCollection<ITabPage> Tabs { get; } = new();
public void AddNewTab()
{
var vm = new MyTabEditorViewModel();
Tabs.Add(vm);
}
XAML.cs
private void NewTab_Executed(object sender, ExecutedRoutedEventArgs e)
{
ViewModel.AddNewJob();
Multitab.SelectedIndex = Multitab.Items.Count - 1;
var last = Multitab.SelectedIndex;
this.OneWayBind(ViewModel, vm => vm.Tabs[last], v => GAH WHAT GOES HERE?!?);
}
And this is the part where I get lost. How do I set up the bindings to bind the new VM to the view that gets created for it? Multitab.SelectedItem returns the VM, not the View, and I can't seem to find any way to obtain the newly-created View object in order to bind it.
Does anyone know how to set this up properly?
Please refer to the below sample code.
Window1.xaml:
<reactiveui:ReactiveWindow x:Class="WpfApp1.Window1"
x:TypeArguments="local:ViewModel"
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:WpfApp1"
xmlns:reactiveui="http://reactiveui.net"
mc:Ignorable="d"
Title="Window1" Height="450" Width="800">
<Grid>
<TabControl Name="Multitab">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<reactiveui:ViewModelViewHost ViewModel="{Binding}" />
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</Grid>
</reactiveui:ReactiveWindow>
Window.xaml.cs:
public partial class Window1 : ReactiveWindow<ViewModel>
{
public Window1()
{
InitializeComponent();
ViewModel = new ViewModel();
this.WhenActivated(disposableRegistration =>
{
this.OneWayBind(ViewModel,
viewModel => viewModel.Tabs,
view => view.Multitab.ItemsSource)
.DisposeWith(disposableRegistration);
});
}
}
View Model:
public class ViewModel
{
public ObservableCollection<ITabPage> Tabs { get; } =
new ObservableCollection<ITabPage>() { new MyTabEditorViewModel() };
}
Tab View Model:
public interface ITabPage { }
public class MyTabEditorViewModel : ITabPage
{
public string Name { get; } = "Name...";
}
TabView.xaml:
<reactiveui:ReactiveUserControl x:Class="WpfApp1.TabEditorView"
x:TypeArguments="local:MyTabEditorViewModel"
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:reactiveui="http://reactiveui.net"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<TextBlock>Tab content...</TextBlock>
</Grid>
</reactiveui:ReactiveUserControl>
TabView.xaml.cs:
public partial class TabEditorView : ReactiveUserControl<MyTabEditorViewModel>
{
public TabEditorView()
{
InitializeComponent();
}
}
I am trying to make an app using using MVVMLight that has a sidebar with buttons, each button shows a new usercontrol hosted in a ContentControl. When the user clicks the buttons in the sidebar (Show View1 / Show View2) it shows the views correctly.
My problems arise when the user has already shown a View (it could be View1 or View2 ), say View1 and click (Show View1) ** again ** View1 controls remain with the same values and I would like to show the same view with all controls as if it had restarted. (I know that I could reset all controls within the user control (View1) but my application requires having a new instance of the view every time the button is clicked).
Somehow, in the same scenario when the user is in View 1, switch to view 2 and return to view 1, a new instance is created and shown as I would like. I would like to get the same result without the need to switch to view 2 and return.
Here is a minimal reproducible example of the issue:
ViewModelLocator.cs
using CommonServiceLocator;
using GalaSoft.MvvmLight.Ioc;
namespace SidebarApp.ViewModel
{
public class ViewModelLocator
{
/// <summary>
/// Initializes a new instance of the ViewModelLocator class.
/// </summary>
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
// Register viewmodels
SimpleIoc.Default.Register<MainViewModel>();
SimpleIoc.Default.Register<View1ViewModel>();
SimpleIoc.Default.Register<View2ViewModel>();
}
public MainViewModel Main { get { return ServiceLocator.Current.GetInstance<MainViewModel>(); } }
public View1ViewModel View1Vm { get { return ServiceLocator.Current.GetInstance<View1ViewModel>(); } }
public View2ViewModel View2Vm { get { return ServiceLocator.Current.GetInstance<View2ViewModel>(); } }
public static void Cleanup()
{
// TODO Clear the ViewModels
}
}
}
MainViewModel.cs
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System.Windows.Input;
namespace SidebarApp.ViewModel
{
public class MainViewModel : ViewModelBase
{
// Commands
public ICommand ShowView1Command { get; private set; }
public ICommand ShowView2Command { get; private set; }
/// <summary>
/// Property that will cointain the current viewmodel to show
/// ViewModelBase inplements ObservableObject class which imlements INotifyPropertyChanged
/// </summary>
public ViewModelBase CurrentViewModel { get; set; }
/// <summary>
/// Initializes a new instance of the MainViewModel class.
/// </summary>
public MainViewModel()
{
this.ShowView1Command = new RelayCommand(ShowView1);
this.ShowView2Command = new RelayCommand(ShowView2);
}
private void ShowView1()
{
// I tried this but it doesn't work
//CurrentViewModel = null or View2ViewModel;
CurrentViewModel = new View1ViewModel();
}
private void ShowView2()
{
CurrentViewModel = new View2ViewModel();
}
}
}
MainWindow.xaml
<Window x:Class="SidebarApp.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:SidebarApp"
mc:Ignorable="d"
DataContext="{Binding Main, Source={StaticResource Locator}}"
Title="MainWindow" Height="348.965" Width="560.683">
<Window.Resources>
<DataTemplate DataType="{x:Type local:View1ViewModel}">
<local:View1View />
</DataTemplate>
<DataTemplate DataType="{x:Type local:View2ViewModel}">
<local:View2View />
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.3*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel>
<Button Command="{Binding ShowView1Command}">Show View1</Button>
<Button Command="{Binding ShowView2Command}">Show View2</Button>
</StackPanel>
<ContentControl Grid.Column="1" Content="{Binding Path=CurrentViewModel}"></ContentControl>
</Grid>
</Window>
View1View.xaml
<UserControl x:Class="SidebarApp.View1View"
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:SidebarApp"
mc:Ignorable="d"
DataContext="{Binding View1Vm, Source={StaticResource Locator}}"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="LightPink">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock HorizontalAlignment="Center" Text="Welcome to View 1" FontSize="20"/>
<TextBox HorizontalAlignment="Stretch" Text="Original text value"/>
<CheckBox Content="Some boolean value"/>
</StackPanel>
</Grid>
</UserControl>
View1ViewModel.cs
using GalaSoft.MvvmLight;
namespace SidebarApp
{
public class View1ViewModel : ViewModelBase
{
public View1ViewModel()
{
}
}
}
View2View.xaml
<UserControl x:Class="SidebarApp.View2View"
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:SidebarApp"
mc:Ignorable="d"
DataContext="{Binding View2Vm, Source={StaticResource Locator}}"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="LightCyan">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock HorizontalAlignment="Center" Text="Welcome to View 2" FontSize="20"/>
<TextBox HorizontalAlignment="Stretch" Text="Some text in view2"/>
<Button Content="Button"/>
</StackPanel>
</Grid>
</UserControl>
View2ViewModel.cs
using GalaSoft.MvvmLight;
namespace SidebarApp
{
public class View2ViewModel : ViewModelBase
{
public View2ViewModel()
{
}
}
}
App.xaml
<Application x:Class="SidebarApp.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:SidebarApp" StartupUri="MainWindow.xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" d1p1:Ignorable="d" xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006">
<Application.Resources>
<ResourceDictionary>
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" xmlns:vm="clr-namespace:SidebarApp.ViewModel" />
</ResourceDictionary>
</Application.Resources>
</Application>
For example I enter to the view1 and change the value of the textbox ("Original text value") to another value and I click again in Show View1 the text and everything in the usercontrol stays the same but when I switch to view2 and go back to view1 a new usercontrol is shown with his original values.
This might feel like something of a workaround, but it works. Hopefully it will prove useful. (Obviously make same changes to View2View view/view model).
ViewModelLocator.cs
public View1ViewModel View1Vm { get { return new View1ViewModel(); } }
MainViewViewModel.cs
private void ShowView1()
{
CurrentViewModel = new ViewModelLocator().View1Vm;
}
View1View.xaml
<UserControl x:Class="SidebarApp.View1View"
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:SidebarApp"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="LightPink">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock HorizontalAlignment="Center" Text="Welcome to View 1" FontSize="20"/>
<TextBox HorizontalAlignment="Stretch" Text="{Binding Path=View1Text, Mode=TwoWay}"/>
<CheckBox Content="Some boolean value" IsChecked="{Binding Path=CheckBoxChecked, Mode=TwoWay}"/>
</StackPanel>
</Grid>
</UserControl>
View1ViewModel.cs
public class View1ViewModel : ViewModelBase
{
private string _view1Text;
private bool _checkBoxedChecked;
public string View1Text
{
get
{
return _view1Text;
}
set
{
_view1Text = value;
RaisePropertyChanged("View1Text");
}
}
public bool CheckBoxChecked
{
get
{
return _checkBoxedChecked;
}
set
{
_checkBoxedChecked = value;
RaisePropertyChanged("CheckBoxChecked");
}
}
public View1ViewModel()
{
View1Text = "Original text value";
}
}
I need to extend a ListBox with a custom ItemTemplate but when I run my code the ItemTemplate does not get applied?
<ListBox x:Class="ExtendedCheckedListbox"
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:ExtListBoxPOC"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Description}" VerticalAlignment="Stretch" VerticalContentAlignment="Center" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
private YesNoModel YesNo = new YesNoModel();
{
DataContext = YesNo;
cbl.ItemsSource = YesNo;
}
My main Window XAML which uses the control called cbl which has the ItemsSource set in code behind:
<Window x:Class="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:ExtListBoxPOC"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<local:ExtendedCheckedListbox x:Name="cbl" HorizontalAlignment="Left" Height="300" Margin="10" VerticalAlignment="Top" Width="300"/>
</Grid>
</Window>
The Model class is this:
public class YesNoModel
{
public string Description { get; set; }
public int Value { get; set; }
}
And I am adding items here:
{
YesNo.Add(new YesNoModel() { Description = "Yes", Value = 1 });
YesNo.Add(new YesNoModel() { Description = "No", Value = 2 });
YesNo.Add(new YesNoModel() { Description = "N/A", Value = 3 });
}
Code behind the ExtendedCheckedListbox View:
public class ExtendedCheckedListbox : ListBox
{
}
Your derived ListBox simply ignores the XAML, because you did apparently not call InitializeComponent() anywhere.
However, the usual way to derive from a control is to create a default Style in Themes\Generic.xaml. Add a "custom control" to your Visual Studio project and modify it like this:
public class ExtendedCheckedListBox : ListBox
{
static ExtendedCheckedListBox()
{
DefaultStyleKeyProperty.OverrideMetadata(
typeof(ExtendedCheckedListBox),
new FrameworkPropertyMetadata(typeof(ExtendedCheckedListBox)));
}
}
Then change the content of the generated Themes\Generic.xaml file to this:
<Style TargetType="local:ExtendedCheckedListBox">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<CheckBox Content="{Binding Description}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
See Control Authoring Overview for details.
Using Xceed DataGrid for WPF
How can you use generated sample data source (generated in Expression Blend) as the source for DataGridCollectionViewSource? Is it possible?
<xcdg:DataGridCollectionViewSource x:Key="cvsSample"
Source="{Binding Source={x:Static Application.Current},Path=SampleDataSource}"/>
Doing this throw an error:
A value of type 'DataGridCollectionViewSource' cannot be added to a collection or dictionary of type 'UIElementCollection'.
I can set it directly in the DataGridControl like so:
<xcdg:DataGridControl ItemTemplate="{DynamicResource ItemTemplate}"
ItemsSource="{Binding Collection, Source={StaticResource SampleDataSource}}"
UpdateSourceTrigger="CellContentChanged"
Margin="10">
</xcdg:DataGridControl>
But I want to use the DataGridCollectionViewSource as it allows you to use the filtering, grouping etc. functionality.
Try this:
XAML:
<Window x:Class="WpfApp1.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:xcdg="http://schemas.xceed.com/wpf/xaml/datagrid"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<xcdg:DataGridCollectionViewSource x:Key="cvsSample" Source="{Binding}" />
</Window.Resources>
<Grid>
<xcdg:DataGridControl ItemsSource="{Binding Source={StaticResource cvsSample}}"/>
</Grid>
</Window>
CS:
using Xceed.Wpf.Samples.SampleData;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = SampleDataProvider.GetProducts();
}
}
Look at jstreet's answer, but if that doesnt work for you, you can try doing what I did.
In Visual Studio go to Project > Add Reference > Extensions and add Xceed.Wpf.DataGrid.Samples.SampleData (remember to check the little box next to it).
App.xaml.cs
public partial class App : System.Windows.Application
{
protected override void OnStartup(StartupEventArgs e)
{
Xceed.Wpf.DataGrid.Licenser.LicenseKey = "XXXXX-XXXXX-XXXXX-XXXX";
DataSet musicDataSet = Xceed.Wpf.DataGrid.Samples.SampleData.DataProvider.GetMusicLibraryDataSet();
m_songs = musicDataSet.Tables["Songs"];
base.OnStartup(e);
}
private DataTable m_songs;
public DataTable Songs
{
get
{
return m_songs;
}
}
}
MainWindow.xaml
<Window.Resources>
<xcdg:DataGridCollectionViewSource x:Key="cvsSongs"
Source="{Binding Source={x:Static Application.Current},Path=Songs}">
</xcdg:DataGridCollectionViewSource>
</Window.Resources>
<Grid>
<xcdg:DataGridControl ItemsSource="{Binding Source={StaticResource cvsSongs}}"/>
</Grid>
Can't believe I struggled this much just to have missed a reference...
I am new to WPF so please bear with me. In a UniformGrid I put multiple UserControls which are created at run time. What I want to know is how to drag and drop, move or swap the position of these controls at run time. I have searched all over the internet but couldn't find anything fruitful.
The UniformGrid is a layout control. You cannot interact directly with it.
To achieve what you need, I propose you this solution.
Create a ItemsControl element
Change the ItemsPanel to a UniformGrid
Use the GongSolutions.Wpf.DragDrop project. You can install it from nuGet http://www.nuget.org/packages/gong-wpf-dragdrop/
This solution can be written without any code-behind or VM code.
<Window x:Class="WpfApplication6.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:dd="clr-namespace:GongSolutions.Wpf.DragDrop;assembly=GongSolutions.Wpf.DragDrop"
Title="MainWindow" Height="350" Width="525">
<ItemsControl Height="150"
dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Items>
<system:String>Item 1</system:String>
<system:String>Item 2</system:String>
<system:String>Item 3</system:String>
</ItemsControl.Items>
</ItemsControl>
</Window>
Update:
If you need to drag items from another control then add this to your code-behind file.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
SourceOfItems = new List<string>() { "Source 1", "Source 2", "Source 3" };
Items = new ObservableCollection<string>() { "Item 1", "Item 2", "Item 3" };
}
public ObservableCollection<string> Items { get; private set; }
public List<string> SourceOfItems { get; private set; }
}
And update your XAML like this:
<Window x:Class="WpfApplication6.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dd="clr-namespace:GongSolutions.Wpf.DragDrop;assembly=GongSolutions.Wpf.DragDrop"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<ListBox ItemsSource="{Binding SourceOfItems}"
dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="False"/>
<ItemsControl Height="150"
dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True"
ItemsSource="{Binding Items}"
Background="Plum"
>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</StackPanel>
</Window>