WPF将数据对象从主应用程序UI传递给用户控件

时间:2013-06-09 23:06:35

标签: wpf user-controls relativesource

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

我知道DependancyProperties和RelativeSource是实现这一目标的方法,但由于缺乏WPF专业知识,我不确定如何实现这一点。有人可以帮助我。

由于

我有三个xaml文件,MainWindow,AlsTabUC(UserControl)和RangingTabUC(UserControl)。我有一个对象代表一个同时执行范围和环境光测量的设备,并且我喜欢在不同的标签中执行这些活动。

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

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

MainWindow - 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>

MainWindow - 代码

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();
    }
}

rangeTabUC-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>

rangeTabUC-代码

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

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

2 个答案:

答案 0 :(得分:2)

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

将属性SensorDevice添加到您的UserControl AlsTabUCrangingTabUC,以便在MainWindow中调用InitializeComponent后将SensorDevice的引用传递给UserControl。

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();

答案 1 :(得分:1)

我认为您调用SensorDevice的方法来获取环境值或范围值,因此您可以定义继承自INotifyPropertyChanged接口的viewmodel类SensorDevice,并定义两个属性,如Ambient或Range,并调用OnPropertyChanged(“Ambient”)。之后,您需要在xaml中初始化viewmodel,并将其传递给tabcontrol的DataContext。您的usercontrol只绑定到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>

相关问题