如何将 Ninject 用于 MVVM 和 WPF
How to Use Ninject with MVVM and WPF
我正在努力使用 WPF 和 MVVM 模式构建应用程序。
在此应用程序中,我在 MainView 中有三个按钮 - 相机、锅炉、温度传感器。当我按下某个按钮时,它会在 window 的第二部分打开附加控件,其中包含有关所选小工具的信息。
我已经做到了,但是架构不好,因为主窗体“知道”某些对象。我的 MainView (XAML) 中有这段代码,它看起来不应该是这样的。
<Window ...>
<Grid>
<Grid.ColumnDefinitions>
</Grid.ColumnDefinitions>
<StackPanel>
<Button Content="Камера"
Command="{Binding NavigationCameraCommand}"
Margin="5"
Height="30"/>
<Button Content="Котёл"
Command="{Binding NavigateBoilerCommand}"
Margin="5"
Height="30"/>
<Button Content="Датчик температуры"
Command="{Binding NavigationTemperatureSensorCommand}"
Margin="5"
Height="30"/>
</StackPanel>
<ContentControl Grid.Column="1" Content="{Binding CurrentViewModel}">
<ContentControl.Resources>
<DataTemplate DataType="{x:Type viewmodels:CameraViewModel}">
<views:CameraView/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:BoilerViewModel}">
<views:BoilerVIew/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:TemperatureSensorViewModel}">
<views:TemperatureSensorView/>
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
</Grid>
</Window>
我需要用Ninject来处理这个问题。据我了解,我需要在定位器中定义成对的视图和模型,然后在注入视图时,将自动确定链接模型,创建它的实例并将其分配给视图上下文。
我还没有找到如何实现的示例。
谁能举例说明如何做到这一点或举例说明(最好有几个观点)?
我在 YouTube 上找到了这个视频,但仍然不明白它在多次观看时效果如何。
https://www.youtube.com/watch?v=yN4SgWHwhgk
看来你想得到另一个结果。
如果您计划在将来添加设备(动态生成按钮并使用自定义视图),您需要为每个设备(传感器、锅炉等)定义基本接口和实现,这应该作为不同的模块(库)。模块应该提供一些元数据、自定义视图和你想要的其他东西。
当您启动您的应用程序时,容器会加载具有已实现的基本接口的程序集,因此您可以获得设备并可以使用元数据动态生成按钮。然后,在必要时,您可以使用提供的视图或其他提供的属性或方法。
interface IDevice
{
IDeviceMetadata Metadata { get; }
UserControl View { get; }
}
interface IDeviceMetadata
{
Guid Key { get; }
string Name { get; }
string Description { get; }
string Version { get; }
}
class App
{
public ICollection<IDevice> Devices { get; private set; }
void LoadDevices()
{
Devices = Container.LoadFromDirectory("path_to_device_libraries(dlls)");
}
}
class DevicesViewModel
{
public IEnumerable<IDevice> Devices => App.Instance.Devices;
public UserControl DeviceView { get { ... } set { ... } } // have to invoke PropertyChanged
public ICommand ShowDeviceViewCommand => Command.Create<IDevice>(ShowDeviceView);
private void ShowDeviceView(IDevice device)
{
DeviceView = device.View;
}
}
<Window>
<Grid>
<ItemsControl ItemsSource="{Binding Devices}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Path=Metadata.Name}"
Command="{Binding Path=DataContext.ShowDeviceViewCommand, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
Margin="5" Height="30"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ContentControl Grid.Column="1" Content="{Binding DeviceView}"/>
</Grid>
</Window>
我正在努力使用 WPF 和 MVVM 模式构建应用程序。 在此应用程序中,我在 MainView 中有三个按钮 - 相机、锅炉、温度传感器。当我按下某个按钮时,它会在 window 的第二部分打开附加控件,其中包含有关所选小工具的信息。 我已经做到了,但是架构不好,因为主窗体“知道”某些对象。我的 MainView (XAML) 中有这段代码,它看起来不应该是这样的。
<Window ...>
<Grid>
<Grid.ColumnDefinitions>
</Grid.ColumnDefinitions>
<StackPanel>
<Button Content="Камера"
Command="{Binding NavigationCameraCommand}"
Margin="5"
Height="30"/>
<Button Content="Котёл"
Command="{Binding NavigateBoilerCommand}"
Margin="5"
Height="30"/>
<Button Content="Датчик температуры"
Command="{Binding NavigationTemperatureSensorCommand}"
Margin="5"
Height="30"/>
</StackPanel>
<ContentControl Grid.Column="1" Content="{Binding CurrentViewModel}">
<ContentControl.Resources>
<DataTemplate DataType="{x:Type viewmodels:CameraViewModel}">
<views:CameraView/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:BoilerViewModel}">
<views:BoilerVIew/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:TemperatureSensorViewModel}">
<views:TemperatureSensorView/>
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
</Grid>
</Window>
我需要用Ninject来处理这个问题。据我了解,我需要在定位器中定义成对的视图和模型,然后在注入视图时,将自动确定链接模型,创建它的实例并将其分配给视图上下文。
我还没有找到如何实现的示例。
谁能举例说明如何做到这一点或举例说明(最好有几个观点)?
我在 YouTube 上找到了这个视频,但仍然不明白它在多次观看时效果如何。 https://www.youtube.com/watch?v=yN4SgWHwhgk
看来你想得到另一个结果。 如果您计划在将来添加设备(动态生成按钮并使用自定义视图),您需要为每个设备(传感器、锅炉等)定义基本接口和实现,这应该作为不同的模块(库)。模块应该提供一些元数据、自定义视图和你想要的其他东西。 当您启动您的应用程序时,容器会加载具有已实现的基本接口的程序集,因此您可以获得设备并可以使用元数据动态生成按钮。然后,在必要时,您可以使用提供的视图或其他提供的属性或方法。
interface IDevice
{
IDeviceMetadata Metadata { get; }
UserControl View { get; }
}
interface IDeviceMetadata
{
Guid Key { get; }
string Name { get; }
string Description { get; }
string Version { get; }
}
class App
{
public ICollection<IDevice> Devices { get; private set; }
void LoadDevices()
{
Devices = Container.LoadFromDirectory("path_to_device_libraries(dlls)");
}
}
class DevicesViewModel
{
public IEnumerable<IDevice> Devices => App.Instance.Devices;
public UserControl DeviceView { get { ... } set { ... } } // have to invoke PropertyChanged
public ICommand ShowDeviceViewCommand => Command.Create<IDevice>(ShowDeviceView);
private void ShowDeviceView(IDevice device)
{
DeviceView = device.View;
}
}
<Window>
<Grid>
<ItemsControl ItemsSource="{Binding Devices}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Path=Metadata.Name}"
Command="{Binding Path=DataContext.ShowDeviceViewCommand, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
Margin="5" Height="30"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ContentControl Grid.Column="1" Content="{Binding DeviceView}"/>
</Grid>
</Window>