如何在 Prism (MVVM) 中使用 Windows.Devices.Enumeration.DevicePicker?
How to use Windows.Devices.Enumeration.DevicePicker with Prism (MVVM)?
我正在开发一个新的 UWP 应用程序,它通过蓝牙与某些硬件进行交互。使用 windows-universal-samples repo 作为指南,我能够成功地获得我想要的工作。
现在我正在尝试使用 Prism 将我在点击事件处理程序中编写的代码重构为视图模型 class。但是我不知道如何处理这个。在我需要在 View 和 ViewModel 之间传递数据的其他场景中,我会在 ViewModel 上创建一个 属性 并将其绑定到视图 XAML.
中的控件
问题是 Windows.Devices.Enumaration.DevicePicker
的使用方式似乎与 MVVM 模式不兼容。在点击处理程序中,数据和控件合并在一起,我不知道如何在视图模型上制作某种列表 属性,然后将其绑定到视图。这是我正在使用的代码的最简单示例:
async void DiscoverButton_OnClick(object sender, RoutedEventArgs e)
{
var devicePicker = new DevicePicker();
devicePicker.Filter.SupportedDeviceSelectors.Add(BluetoothLEDevice.GetDeviceSelectorFromPairingState(true));
// Calculate the position to show the picker (right below the buttons)
var ge = DiscoverButton.TransformToVisual(null);
var point = ge.TransformPoint(new Point());
var rect = new Rect(point, new Point(100, 100));
var device = await devicePicker.PickSingleDeviceAsync(rect);
var bluetoothLEDevice = await BluetoothLEDevice.FromIdAsync(device.Id);
}
参见PickSingleDeviceAsync()
直接创建控件。
Now I am trying to refactor the code I wrote in a click event handler into a view model class using Prism. However I don't know how to approach this.
您可以为按钮绑定命令,并使用 CommandParameter 将参数传递给命令。
详情请参考以下代码示例:
<Button x:Name="btn" Content="device" Command="{Binding ClickCommand}" CommandParameter="{Binding ElementName=btn}"></Button>
public class MianViewModel : BindableBase
{
public ICommand ClickCommand
{
get;
private set;
}
public MianViewModel()
{
ClickCommand = new DelegateCommand<object>(ClickedMethod);
}
private async void ClickedMethod(object obj)
{
var devicePicker = new DevicePicker();
devicePicker.Filter.SupportedDeviceSelectors.Add(BluetoothLEDevice.GetDeviceSelectorFromPairingState(true));
// Calculate the position to show the picker (right below the buttons)
Button DiscoverButton = obj as Button;
if (DiscoverButton != null)
{
var ge = DiscoverButton.TransformToVisual(null);
var point = ge.TransformPoint(new Point());
var rect = new Rect(point, new Point(100, 100));
var device = await devicePicker.PickSingleDeviceAsync(rect);
if (device != null)
{
var bluetoothLEDevice = await BluetoothLEDevice.FromIdAsync(device.Id);
}
}
}
}
我想出的解决方案是放弃 DevicePicker
提供的内置 UI,而是创建我自己的 UI 以与 DeviceWatcher
一起使用。例如:
void StartWatcher()
{
ResultCollection.Clear();
string selector = BluetoothLEDevice.GetDeviceSelector();
DeviceWatcher = DeviceInformation.CreateWatcher(selector);
DeviceWatcher.Added += async (deviceWatcher, deviceInformation) =>
{
await OnUiThread(() =>
{
ResultCollection.Add(deviceInformation);
});
};
DeviceWatcher.Start();
}
其中 ResultCollection
将从视图模型绑定到视图。
我正在开发一个新的 UWP 应用程序,它通过蓝牙与某些硬件进行交互。使用 windows-universal-samples repo 作为指南,我能够成功地获得我想要的工作。
现在我正在尝试使用 Prism 将我在点击事件处理程序中编写的代码重构为视图模型 class。但是我不知道如何处理这个。在我需要在 View 和 ViewModel 之间传递数据的其他场景中,我会在 ViewModel 上创建一个 属性 并将其绑定到视图 XAML.
中的控件问题是 Windows.Devices.Enumaration.DevicePicker
的使用方式似乎与 MVVM 模式不兼容。在点击处理程序中,数据和控件合并在一起,我不知道如何在视图模型上制作某种列表 属性,然后将其绑定到视图。这是我正在使用的代码的最简单示例:
async void DiscoverButton_OnClick(object sender, RoutedEventArgs e)
{
var devicePicker = new DevicePicker();
devicePicker.Filter.SupportedDeviceSelectors.Add(BluetoothLEDevice.GetDeviceSelectorFromPairingState(true));
// Calculate the position to show the picker (right below the buttons)
var ge = DiscoverButton.TransformToVisual(null);
var point = ge.TransformPoint(new Point());
var rect = new Rect(point, new Point(100, 100));
var device = await devicePicker.PickSingleDeviceAsync(rect);
var bluetoothLEDevice = await BluetoothLEDevice.FromIdAsync(device.Id);
}
参见PickSingleDeviceAsync()
直接创建控件。
Now I am trying to refactor the code I wrote in a click event handler into a view model class using Prism. However I don't know how to approach this.
您可以为按钮绑定命令,并使用 CommandParameter 将参数传递给命令。
详情请参考以下代码示例:
<Button x:Name="btn" Content="device" Command="{Binding ClickCommand}" CommandParameter="{Binding ElementName=btn}"></Button>
public class MianViewModel : BindableBase
{
public ICommand ClickCommand
{
get;
private set;
}
public MianViewModel()
{
ClickCommand = new DelegateCommand<object>(ClickedMethod);
}
private async void ClickedMethod(object obj)
{
var devicePicker = new DevicePicker();
devicePicker.Filter.SupportedDeviceSelectors.Add(BluetoothLEDevice.GetDeviceSelectorFromPairingState(true));
// Calculate the position to show the picker (right below the buttons)
Button DiscoverButton = obj as Button;
if (DiscoverButton != null)
{
var ge = DiscoverButton.TransformToVisual(null);
var point = ge.TransformPoint(new Point());
var rect = new Rect(point, new Point(100, 100));
var device = await devicePicker.PickSingleDeviceAsync(rect);
if (device != null)
{
var bluetoothLEDevice = await BluetoothLEDevice.FromIdAsync(device.Id);
}
}
}
}
我想出的解决方案是放弃 DevicePicker
提供的内置 UI,而是创建我自己的 UI 以与 DeviceWatcher
一起使用。例如:
void StartWatcher()
{
ResultCollection.Clear();
string selector = BluetoothLEDevice.GetDeviceSelector();
DeviceWatcher = DeviceInformation.CreateWatcher(selector);
DeviceWatcher.Added += async (deviceWatcher, deviceInformation) =>
{
await OnUiThread(() =>
{
ResultCollection.Add(deviceInformation);
});
};
DeviceWatcher.Start();
}
其中 ResultCollection
将从视图模型绑定到视图。