admin管理员组文章数量:1287882
I have a ScrollViewer
inside of which there's an ItemsControl
element, inside of which I want to display custom views and pass data into them using bindings.
The individual items are of DeviceListItemView
type, which contains DeviceListItemViewModel ViewModel
property. I seem to set ItemsSource
and ItemTemplate
correctly since the ScrollViewer
displays the correct amount of default DeviceListItemView
, but I can't seem to figure out how to pass data to DeviceListItemView.ViewModel
What am I missing?
DeviceListView.xaml
:
<UserControl x:Class="Escape_Room_Hub.UI.DeviceInfo.DeviceList.DeviceListView"
xmlns=";
xmlns:x=";
xmlns:mc=";
xmlns:d=";
xmlns:local="clr-namespace:Escape_Room_Hub.UI.DeviceInfo.DeviceList" xmlns:devicelistitem="clr-namespace:Escape_Room_Hub.UI.DeviceInfo.DeviceListItem"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<ScrollViewer Background="#FF000096">
<ItemsControl Name ="items">
</ItemsControl>
</ScrollViewer>
</Grid>
</UserControl>
DeviceListView.xaml.cs
:
public partial class DeviceListView : UserControl
{
DeviceListViewModel viewModel = new DeviceListViewModel();
public DeviceListView()
{
InitializeComponent();
SetupBindings();
}
private void SetupBindings()
{
var itemViewFactory = new FrameworkElementFactory(typeof(DeviceListItemView));
DataTemplate dataTemplate = new DataTemplate();
dataTemplate.DataType = typeof(DeviceListItemViewModel);
dataTemplate.VisualTree = itemViewFactory;
items.ItemsSource = viewModel.items;
items.ItemTemplate = dataTemplate;
}
}
DeviceListViewModel.cs
:
internal class DeviceListViewModel
{
public List<DeviceListItemViewModel> items { get; set; } = new List<DeviceListItemViewModel>();
public DeviceListViewModel()
{
SetupSubscriptions();
}
private void SetupSubscriptions()
{
// updates items property
}
}
DeviceListItemView.xaml.cs
:
public partial class DeviceListItemView : UserControl
{
public DeviceListItemViewModel ViewModel = new DeviceListItemViewModel();
public DeviceListItemView()
{
InitializeComponent();
}
}
I have a ScrollViewer
inside of which there's an ItemsControl
element, inside of which I want to display custom views and pass data into them using bindings.
The individual items are of DeviceListItemView
type, which contains DeviceListItemViewModel ViewModel
property. I seem to set ItemsSource
and ItemTemplate
correctly since the ScrollViewer
displays the correct amount of default DeviceListItemView
, but I can't seem to figure out how to pass data to DeviceListItemView.ViewModel
What am I missing?
DeviceListView.xaml
:
<UserControl x:Class="Escape_Room_Hub.UI.DeviceInfo.DeviceList.DeviceListView"
xmlns="http://schemas.microsoft/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats./markup-compatibility/2006"
xmlns:d="http://schemas.microsoft/expression/blend/2008"
xmlns:local="clr-namespace:Escape_Room_Hub.UI.DeviceInfo.DeviceList" xmlns:devicelistitem="clr-namespace:Escape_Room_Hub.UI.DeviceInfo.DeviceListItem"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<ScrollViewer Background="#FF000096">
<ItemsControl Name ="items">
</ItemsControl>
</ScrollViewer>
</Grid>
</UserControl>
DeviceListView.xaml.cs
:
public partial class DeviceListView : UserControl
{
DeviceListViewModel viewModel = new DeviceListViewModel();
public DeviceListView()
{
InitializeComponent();
SetupBindings();
}
private void SetupBindings()
{
var itemViewFactory = new FrameworkElementFactory(typeof(DeviceListItemView));
DataTemplate dataTemplate = new DataTemplate();
dataTemplate.DataType = typeof(DeviceListItemViewModel);
dataTemplate.VisualTree = itemViewFactory;
items.ItemsSource = viewModel.items;
items.ItemTemplate = dataTemplate;
}
}
DeviceListViewModel.cs
:
internal class DeviceListViewModel
{
public List<DeviceListItemViewModel> items { get; set; } = new List<DeviceListItemViewModel>();
public DeviceListViewModel()
{
SetupSubscriptions();
}
private void SetupSubscriptions()
{
// updates items property
}
}
DeviceListItemView.xaml.cs
:
public partial class DeviceListItemView : UserControl
{
public DeviceListItemViewModel ViewModel = new DeviceListItemViewModel();
public DeviceListItemView()
{
InitializeComponent();
}
}
Share
Improve this question
edited Feb 24 at 18:04
marc_s
755k184 gold badges1.4k silver badges1.5k bronze badges
asked Feb 24 at 17:37
mag_zbcmag_zbc
6,99214 gold badges43 silver badges64 bronze badges
1
- This question is similar to: WPF: ItemsControl and DataContext. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. – Emperor Eto Commented Feb 24 at 22:20
1 Answer
Reset to default 1How to pass data into a particular item of ItemsControl
This is done be means of the DataContext
property.
DeviceListItemView
should not create a private view model instance. Instead, if you set the ItemTemplate
to a DataTemplate that contains a DeviceListItemView, the DeviceListItemView's DataContext
will automatically be set to the appripriate element in the ItemsSource
collection.
<ItemsControl x:Name="items">
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- DeviceListItemView automatically gets the correct DataContext here -->
<local:DeviceListItemView/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
The SetupBindings
method would only be this:
private void SetupBindings()
{
items.ItemsSource = viewModel.items;
}
DeviceListView
should typically also not have a private view model, but in case it is kind of a "top-level" element, it might perhaps have one. It should however declare a property and bind to it:
public partial class DeviceListView : UserControl
{
public DeviceListViewModel ViewModel { get; } = new DeviceListViewModel();
public DeviceListView()
{
InitializeComponent();
}
}
with
<ItemsControl ItemsSource="{Binding ViewModel.items,
RelativeSource={RelativeSource AncestorType=UserControl}}">
...
</ItemsControl>
In the DeviceListItemView
code you could do this if somehow necessary:
public partial class DeviceListItemView : UserControl
{
private DeviceListItemViewModel viewModel;
public DeviceListItemView()
{
InitializeComponent();
DataContextChanged += (s, e) => viewModel = (DeviceListItemViewModel)DataContext;
}
}
本文标签: cHow to pass data into a particular item of ItemsControlStack Overflow
版权声明:本文标题:c# - How to pass data into a particular item of ItemsControl - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741250409a2365683.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论