Set WPF DataContext from UserControls
本文关键字:UserControls from DataContext WPF Set | 更新日期: 2023-09-27 18:28:15
大家好,我已经搜索了很长时间,但我无法解决我的问题:
我希望在主窗口的列表框中为ProductList中的每个元素都有一个UserControl,它显示一些内容。
我的主窗口XAML代码:
<Window
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:CigaretteAutomation"
xmlns:UserControls="clr-namespace:CigaretteAutomation.UserControls" x:Class="CigaretteAutomation.MainWindow"
mc:Ignorable="d"
Title="HB Sparverein Wiesinger - Zigaretten" WindowState="Maximized">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions></TextBlock>
<ListBox x:Name="lb" Grid.Row="1" Width="Auto" Margin="10" ItemsSource="{Binding ProductList}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<UserControls:UserControlDisplayProduct DataContext="{Binding ProductList/}"></UserControls:UserControlDisplayProduct>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button x:Name="btLogin" Grid.Row="2" Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Click="btLogin_Click"/>
</Grid>
</Window>
我的主窗口XAML.cs文件:
namespace CigaretteAutomation
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
ViewModelMainWindow vm = new ViewModelMainWindow();
InitializeComponent();
this.DataContext = vm;
}
}
}
我的主窗口视图模型(适用于DC):
namespace CigaretteAutomation.ViewModelWindow
{
public class ViewModelMainWindow
{
public ViewModelMainWindow()
{
ProductList = new ObservableCollection<ViewModelProduct>();
// Get all DB Entities
using (CIGARETTES_DBEntities c = new CIGARETTES_DBEntities())
{
foreach (PRODUCT productFromDB in c.PRODUCTS)
{
ViewModelProduct vmProd = new ViewModelProduct(productFromDB);
ProductList.Add(vmProd);
}
}
}
public ObservableCollection<ViewModelProduct> ProductList { get; set; }
}
}
这就是我的用户控制XAML文件:
<UserControl x:Class="CigaretteAutomation.UserControls.UserControlDisplayProduct"
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:CigaretteAutomation.UserControls"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<DockPanel>
<TextBlock DockPanel.Dock="Top" HorizontalAlignment="Center" Text="IMG" FontSize="40" VerticalAlignment="Center"/>
<TextBlock DockPanel.Dock="Bottom" HorizontalAlignment="Center" Text="{Binding Name}"/>
<TextBlock DockPanel.Dock="Bottom" HorizontalAlignment="Center" Text="{Binding Price}" VerticalAlignment="Bottom"/>
</DockPanel>
</UserControl>
最后是我的产品视图模型:
namespace CigaretteAutomation.ViewModelData
{
public class ViewModelProduct : INotifyPropertyChanged
{
public ViewModelProduct(PRODUCT _productFromDB)
{
ProductFromDB = _productFromDB;
_name = ProductFromDB.NAME;
_price = ProductFromDB.PRICE.ToString();
}
public PRODUCT ProductFromDB;
private string _name;
public string Name { get { return _name; } set { this.ChangeAndNotify(ref _name, value); } }
private string _price;
public string Price { get { return _price; } set { this.ChangeAndNotify(ref _price, value); } }
// Notifying
public event PropertyChangedEventHandler PropertyChanged;
public event PropertyChangingEventHandler PropertyChanging;
public bool ChangeAndNotify<T>(ref T field, T value, [CallerMemberName] string propertyName = null, IEqualityComparer comparer = null)
{
if (IsEqual(field, value, comparer))
return false;
if (PropertyChanging == null && PropertyChanged == null)
field = value;
else
{
OnPropertyChanging(propertyName);
field = value;
OnPropertyChanged(propertyName);
}
return true;
}
private bool IsEqual<T>(T field, T value, IEqualityComparer comparer)
{
IEqualityComparer cmp = comparer ?? EqualityComparer<T>.Default;
return cmp.Equals(field, value);
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
protected virtual void OnPropertyChanging([CallerMemberName] string propertyName = null)
{
if (this.PropertyChanging != null)
this.PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
}
}
}
抱歉,我知道到目前为止有很多代码。。。
我的问题是我无法绑定到ProductList中的元素。它总是显示null。。。
我已经尝试过绑定RelativeSource Self,但也不起作用。我感到有点困惑的是,对于我的ProductList中的所有2个项目,都显示了元素,但控件中的属性却没有。
有人能解决那个问题吗?问候!
您可以通过从Datatemplate:中删除DataContext绑定来修复它
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<UserControls:UserControlDisplayProduct/>
</StackPanel>
</DataTemplate>
每个产品项都将通过枚举的产品实例获得相关的数据上下文。这就是多个基于项的控件的工作方式。