WPF Передача объекта данных из пользовательского интерфейса основного приложения в пользовательский элемент управления
У меня есть пользовательские элементы управления, определенные для представления содержимого элементов вкладки, чтобы разделить большой файл XAML на более мелкие файлы. Я хотел бы передать ссылку на объект данных из основного класса пользовательского интерфейса в пользовательские элементы управления.
Я понимаю, что 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();
}
}
ранжирование TABUC- 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 ответа
Поскольку UserControl определены в XAML и инициализируются кодом InitializeComponent вашего MainWindow, вы не можете использовать конструктор для передачи ссылки на SensorDevice в UserControls.
Добавить недвижимость SensorDevice
в ваши UserControls AlsTabUC
а также rangingTabUC
передать ссылку на свой SensorDevice в UserControls после InitializeComponent
вызывается в вашем MainWindow.
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();
Я думаю, что вы вызываете метод SensorDevice для получения значения окружения или диапазона, поэтому вы можете определить свой класс модели представления SensorDevice, унаследованный от интерфейса INotifyPropertyChanged, и определить два свойства, таких как Ambient или Range, и вызвать OnPropertyChanged("Ambient"). После этого вам нужно инициализировать вашу модель представления в xaml и передать ее в DataContext tabcontrol. Ваш usercontrol просто привязывается к свойству Ambient или Range.
Код как это:
ViewModel
public class SensorDevice : INotifyPropertyChanged
{приватная строка _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>