【问题标题】:WPF Passing data object from Main application UI to user controlWPF将数据对象从主应用程序UI传递到用户控件
【发布时间】:2013-06-09 23:06:34
【问题描述】:

我定义了用户控件来表示选项卡项的内容,以便将大型 XAML 文件拆分为较小的文件。我想将从主 UI 类对数据对象的引用传递给用户控件。

我知道 DependancyProperties 和 RelativeSource 是实现这一点的方法,但由于我缺乏 WPF 专业知识,我不确定如何实现这一点。谁能帮帮我。

谢谢

我有三个 xaml 文件,MainWindow、AlsTabUC (UserControl) 和 RangingTabUC (UserControl)。我有一个对象表示一个设备,该设备执行范围和环境光测量,并且希望在单独的选项卡中执行这些活动。

对象 m_mySensorDevice 是 MainWindow 的成员,它是父窗口,我想将此对象传递给两个孩子,以便他们可以执行 readAmbientLight 和 readRange 方法。

当然,我提供了非常基本的示例代码来进行说明。实际上,这些选项卡包含更多信息(以及其他选项卡),因此是用户控件的原因。

主窗口 - XAML

    <Window.Resources>
        <System:String x:Key="strTabHeaderRanging">Ranging</System:String>
        <System:String x:Key="strTabHeaderALS">ALS</System:String>
    </Window.Resources>
    <Grid>
        <TabControl Name="MainTab" TabStripPlacement="Top"
                    Margin="0,20,0,10"
                    SelectionChanged="mainTab_SelectionChanged" >
            <TabItem Name="tabItemRanging"
                     Header="{Binding Source={StaticResource strTabHeaderRanging}}">
            <Grid>
                <my:rangingTabUC HorizontalAlignment="Center"
                                 VerticalAlignment="Center"
                                 x:Name="rangingTabUC1"/>
            </Grid>
            </TabItem>
            <TabItem Name="tabItemAls"
                  Header="{Binding Source={StaticResource strTabHeaderALS}}">
                <Grid>
                    <my:AlsTabUC HorizontalAlignment="Center"
                                 VerticalAlignment="Center"
                                 x:Name="alsTabUC1" /> 
                </Grid>
            </TabItem>
        </TabControl>
    </Grid>
</Window>

主窗口 - 代码

public partial class MainWindow : Window
{
    SensorDevice m_mySensorDevice;
    public MainWindow()
    {
        m_mySensorDevice = new SensorDevice();
        InitializeComponent();
    }
    private void mainTab_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
    }
    private void Window_Loaded(object sender, RoutedEventArgs e)
    {

    }
}

public class SensorDevice
{
}

AlsTabUC - XAML

<UserControl x:Class="TabUserControls.AlsTabUC">
    <Grid>
        <Button Height="25" Width="100" Name="readAmbientLight"
                HorizontalAlignment="Center"  VerticalAlignment="Center"
                Click="readAmbientLight_Click" Margin="2">
            Read Amb Light
        </Button>
    </Grid>
</UserControl>

AlsTabUC - 代码

public partial class AlsTabUC : UserControl
{
    public AlsTabUC()
    {
        InitializeComponent();
    }

    private void readAmbientLight_Click(object sender, RoutedEventArgs e)
    {
        m_mySensorDevice.readAmbientLight();
    }
}

rangingTabUC-XAML

<UserControl x:Class="TabUserControls.rangingTabUC">
    <Grid>
        <Button Height="25" Width="100" Name="readRange"
                HorizontalAlignment="Center"  VerticalAlignment="Center"
                Click="readRange_Click" Margin="2">
            Read Range
        </Button>  
    </Grid>
</UserControl>

rangingTabUC-代码

public partial class rangingTabUC : UserControl
{
    public rangingTabUC()
    {
        InitializeComponent();
    }

    private void readRange_Click(object sender, RoutedEventArgs e)
    {
        m_mySensorDevice.readRange();
    }
}

【问题讨论】:

  • 发布相关代码和 XAML。此外,WPF 中视图之间的层次关系通常表现在 ViewModel 级别,而不是 View 级别。这是在 MVVM ViewModel-First 方法中。
  • 我已按要求发布了代码和 XAML。谢谢。
  • 我没有看到这里定义的任何 DataContext,所以我只是提供这个建议:您可以在 UserControl 中使用从 MainWindow 继承的 DataContext,然后像往常一样调用它的方法。

标签: wpf user-controls relativesource


【解决方案1】:

由于 UserControl 在 XAML 中定义并由 MainWindow 的代码 InitializeComponent 初始化,因此您无法使用构造函数将 SensorDevice 的引用传递给 UserControl。

在您的主窗口中调用InitializeComponent 后,将属性SensorDevice 添加到您的用户控件AlsTabUCrangingTabUC 以将您的传感器设备的引用传递给您的用户控件。

public SensorDevice Sensor {
    get;
    set;
}

MainWindow 的构造函数更改为以下内容

public MainWindow()
{
    m_mySensorDevice = new SensorDevice();
    InitializeComponent();

    // Pass reference of SensorDevice to UserControls
    rangingTabUC1.Sensor = m_mySensorDevice; 
    alsTabUC1.Sensor = m_mySensorDevice;
}

在您的 UserControls 中,您可以使用该属性来调用 SensorDevice 上的方法

SensorDevice.readAmbientLight();

SensorDevice.readRange();

【讨论】:

  • 谢谢。这正是我想要的。
【解决方案2】:

我认为你调用 SensorDevice 的方法来获取环境值或范围值,因此你可以定义从 INotifyPropertyChanged 接口继承的视图模型类 SensorDevice,并定义两个属性,如 Ambient 或 Range,并调用 OnPropertyChanged("Ambient")。之后,您需要在 xaml 中初始化您的视图模型,并将其传递给 tabcontrol 的 DataContext。您的用户控件只是绑定到 Ambient 或 Range 属性。

这样的代码:

视图模型

public class SensorDevice : INotifyPropertyChanged
{
    private string _ambient = string.Empty;

    public string Ambient
    {
        get {return _ambient;}
        set 
        {
            _ambient = value;
            OnPropertyChanged("Ambient");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;

        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Xaml 之类的:

<Window.Resources>
    <your_namespace_name:SensorDevice x:Key="DeviceVM" />
</Window.Resources>

<TabControl DataContext="{Binding Source={StaticResource DeviceVM}}">
    <TabItem Name="tabItemRanging"
             Header="{Binding Source={StaticResource strTabHeaderRanging}}">
        <TextBlock Text="{Binding Path=Ambient}" />
    </TabItem>
</TabControl>

【讨论】:

    猜你喜欢
    • 2013-07-23
    • 2013-10-18
    • 1970-01-01
    • 1970-01-01
    • 2021-11-12
    • 1970-01-01
    • 2022-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多