我定义了用户控件来表示选项卡项的内容,以便将大型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();
}
}
答案 0 :(得分:2)
由于UserControl是在XAML中定义的并且由MainWindow的代码InitializeComponent初始化,因此您无法使用构造函数将SensorDevice的引用传递给UserControl。
将属性SensorDevice
添加到您的UserControl AlsTabUC
和rangingTabUC
,以便在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>