如何将 MainWindow 上的自定义属性放入 UserControl(来自 UserControl 库/DLL)?

Posted

技术标签:

【中文标题】如何将 MainWindow 上的自定义属性放入 UserControl(来自 UserControl 库/DLL)?【英文标题】:How to get custom property on MainWindow into a UserControl (from UserControl library/DLL)? 【发布时间】:2021-04-21 01:01:21 【问题描述】:

我在一个库中有一组UserControls,但由于该库与MainWindow 位于不同的命名空间中,我似乎无法获得一个UserControl 来检索List<features>来自MainWindow

我怀疑这是因为UserControl 不知道MainWindow,而且它不是故意的,因为它在 DLL 库中。由于UserControl 在 DLL 中,它应该与命名空间无关,但仍然能够获得所需的内容。

所以下面我将一些 XAML 和相关 C# 代码隐藏在您可以在 UserControls ListBox 上看到的位置,我正在尝试从 MainWindow 检索 features 列表。

<UserControl x:Class="FlatControls.MyListBox"
             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:FlatControls"
             mc:Ignorable="d" 
             d:DesignHeight="34" d:DesignWidth="100" MaxHeight="34" MaxWidth="100" x:Name="root">
   <ListBox x:Name="listBox">
</UserControl>
public MyListBox()

   InitializeComponent();
   listBox.Items = ???????????

<Window x:Class="MyApp.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:WpfApp4"
        xmlns:FC="clr-namespace:FlatControls;assembly=FlatControls"
        mc:Ignorable="d"
        Title="MainWindow" Height="1000" Width="1900" WindowState="Maximized" RenderOptions.BitmapScalingMode="Fant">
   <Grid>
      xyz
   </Grid>
<Window>
namespace MyApp

   public List<string> features = new List<string>();

   public MainWindow()
   
      InitializeComponent();
      features.Add("Concave");
      features.Add("Convex");
   

任何帮助都将不胜感激,无论是通过绑定还是代码隐藏:D

【问题讨论】:

我不知道您的代码中的确切问题是什么,但已经存在类似的问题,并且在 *** 中提供了经过验证的解决方案。请查看链接:Similar Solution Link 我看了看,不幸的是这告诉MainWindow它可以使用DLL,但是DLL仍然不知道MainWindow。我可以添加对 UserControl 的类似引用,以便能够指向 MainWindow,但这会使 UserControl 无法在其他项目中重用。 【参考方案1】:

您的自定义UserControl 中的ListBox 必须从某个地方绑定它的ItemsSource。您应该在您的 MyListBox 中创建一个 ItemsSource 依赖属性以启用从外部绑定集合。

public partial class MyListBox : UserControl

   public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register(
      nameof(ItemsSource), typeof(IEnumerable), typeof(MyListBox), new PropertyMetadata());

   public IEnumerable ItemsSource
   
      get => (IEnumerable)GetValue(ItemsSourceProperty);
      set => SetValue(ItemsSourceProperty, value);
   

   public MyListBox()
   
      InitializeComponent();
   

MyListBox 用户控件的标记中,使用RelativeSource 绑定绑定到此属性。

<UserControl x:Class="FlatControls.MyListBox"
             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:FlatControls"
             mc:Ignorable="d" 
             d:DesignHeight="34" d:DesignWidth="100" MaxHeight="34" MaxWidth="100" x:Name="root">
   <ListBox x:Name="listBox" ItemsSource="Binding ItemsSource, RelativeSource=RelativeSource AncestorType=x:Type local:MyListBox"/>
</UserControl>

现在,在您的MainWindow 中使用控件(您已经添加了相应的 XML 命名空间)。

<Window x:Class="MyApp.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:WpfApp4"
        xmlns:FC="clr-namespace:FlatControls;assembly=FlatControls"
        mc:Ignorable="d"
        Title="MainWindow" Height="1000" Width="1900" WindowState="Maximized" RenderOptions.BitmapScalingMode="Fant">
    <Grid>
       <FC:MyListBox x:Name="MyListBox"/>
    </Grid>
<Window>

最后,将MyListBox 控件的ItemsSource 属性分配给features 集合。

public MainWindow()

   InitializeComponent();

   features.Add("Concave");
   features.Add("Convex");

   MyListBox.ItemsSource = Features;

或者,为您的项目公开属性 Features 并将其绑定到 XAML。

public List<string> Features  get; 
<FC:MyListBox ItemsSource="Binding Features"/>

【讨论】:

【参考方案2】:

正如@thatguy 所说,你可以用他的方式去做。 当然,如果你喜欢在 view.cs 中编写代码,你可以使用“FieldModifier”字样来装饰你的 MyListBox 中的列表框:

    <ListBox x:Name="listBox" x:FieldModifier="public" />

在您的 MainWindow 中,您可以获得列表框实例,当然,您可以像这样设置它的 itemsource:

 public MainWindow()
    
        InitializeComponent();

        this.userControl.listBox.ItemsSource = new List<string>()  "11","22","33";
    

【讨论】:

以上是关于如何将 MainWindow 上的自定义属性放入 UserControl(来自 UserControl 库/DLL)?的主要内容,如果未能解决你的问题,请参考以下文章

Asp.Net WebApi 上的自定义授权属性

SolrCloud上的自定义分片或自动分片?

如何在 Qslider 上的自定义位置放置刻度?

在 WPF C# 中无法访问用户控件的自定义属性

谷歌地图上的自定义缩放级别

Qt Creator - UI 类的自定义命名空间