C# xamarin广播接收机访问视图模型
注释:Xamarin 4.2.1.64,Visual Studio 2015 proff 我已经创建了一个跨平台的应用程序,可以在扫描条形码的android设备上运行 当前扫描时,软件具有可选的输出模式(缓冲区、键盘、剪贴板和意图) 当前正在使用键盘模式 流量 用户单击设备按钮扫描条形码,软件尝试转储到屏幕上的输入,如果不是,则将其替换为选项卡(应用程序在启动时将焦点设置为输入字段)。当点击应用程序上的按钮时,它会调用我的服务来查询一组数据并返回结果,然后更新结果列表以供用户查看 我需要更改的流量 用户单击设备按钮扫描条形码,只有这一次设备被设置为意图和广播,我的应用程序接收器接收广播,从意图中读取条形码并调用我的viewmodel以使用条形码更新字段。viewmodel现在将更改为检测字段更改并相应地运行该方法 到目前为止的代码 便携式XamlC# xamarin广播接收机访问视图模型,c#,android,mvvm,xamarin,C#,Android,Mvvm,Xamarin,注释:Xamarin 4.2.1.64,Visual Studio 2015 proff 我已经创建了一个跨平台的应用程序,可以在扫描条形码的android设备上运行 当前扫描时,软件具有可选的输出模式(缓冲区、键盘、剪贴板和意图) 当前正在使用键盘模式 流量 用户单击设备按钮扫描条形码,软件尝试转储到屏幕上的输入,如果不是,则将其替换为选项卡(应用程序在启动时将焦点设置为输入字段)。当点击应用程序上的按钮时,它会调用我的服务来查询一组数据并返回结果,然后更新结果列表以供用户查看 我需要更改的流
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="StockCheckApp.Views.ScannerPage"
xmlns:ViewModels="clr-namespace:StockCheckApp.ViewModels;assembly=StockCheckApp">
<Label Text="{Binding MainText}" VerticalOptions="Center" HorizontalOptions="Center" />
<StackLayout Orientation="Vertical">
<Entry x:Name="myBox" Text="{Binding UserInput, Mode=TwoWay}" />
<Button Text="Check Stock" Command="{Binding PostCommand}"/>
<ListView ItemsSource="{Binding StockList}"
HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical" Padding="12,6">
<Label Text="{Binding St_Code}" FontSize="24" />
<Label Text="{Binding St_Desc}" />
<Label Text="{Binding Sl_Loc}" />
<Label Text="{Binding Sa_Datetime}" />
<Label Text="{Binding Sa_Qty}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
便携式主视图模型
public class MainViewModel : INotifyPropertyChanged
{
ScannerPage page;
private List<Stock> _stockList;
private string _userInput;
public List<Stock> StockList
{
get { return _stockList; }
set
{
_stockList = value;
OnPropertyChanged();
}
}
public string UserInput
{
get { return _userInput; }
set
{
_userInput = value;
OnPropertyChanged();
}
}
public MainViewModel(ScannerPage parent)
{
page = parent;
page.MyBox.Focus();
}
public Command PostCommand
{
get
{
return new Command(async () =>
{
var stockService = new StockService();
StockList = await stockService.GetStockAsync(UserInput);
page.MyBox.Focus();
});
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
//use this to clear? then reset focus?
}
}
我被困在什么上
我一步一步地执行,代码就到达了断点,但在这个阶段,我需要我的接收器以某种方式更新输入字段
我还不熟悉Xamarin,而且我学到了很多,所以我意识到这可能是一个简单的答案
同时
我打算做的对吗?是否接收条形码编号并访问viewmodels“userinput”属性并对其进行更改?os我是否应该访问视图上的字段并对其进行更改,然后允许我的属性更改方法执行业务逻辑?您可以使用Xamarin.Forms附带的消息中心 让您的ViewModel
订阅来自您服务的事件的MessagingCenter,然后使用该事件更新绑定到该字段的属性。如果您的PCL中需要一个类型来映射订阅,请在PCL中为您的服务创建一个不需要任何实际方法契约的接口,然后让您的服务实现它,以便您可以使用强类型设置订阅:
// in your PCL
public interface IScanReceiver
{
}
// in your android project
public class Receiver1 : BroadcastReceiver, IScanReceiver
// in your viewmodel
MessagingCenter.Subscribe<IScanReceiver>();
//在您的PCL中
公共接口IScanReceiver
{
}
//在你的android项目中
公共类接收者1:广播接收者,IScanReceiver
//在您的viewmodel中
MessagingCenter.Subscribe();
或者,您可以在依赖项服务中设置ViewModels,然后使用服务定位器(anti)模式查找ViewModel实例并更新绑定到该字段的属性。
MVVM Light:在为您提供执行此操作的工具方面做得非常好。愚蠢的问题1,当您说PCL时,您指的是什么?您的可移植类库。假设您的XAML就在这里。如果您使用的是共享库,那么我所说的一切都是一样的。无论你的ViewModel和View在哪里,我将从Xamarin论坛上的Craig Dunn那里偷一个例子,但它应该有助于解释一下。在本例中,它使用一个活动将消息发送到Xamarin.Forms页面,但您可以使用接收方将其发送到ViewModel或页面:Ok,因此我创建了接口,添加了一个名为Result{get;set:}的属性字符串。我的接收者实现该属性,然后我说Result=decodedBarcode;这很好,但是在我的viewmodel中如何以及在哪里使用messagecenter方法呢?Craig Dunn的例子,基本上是在我的接收器中创建一个messagecenter来发送字符串,然后让我的ScannerPage类订阅消息?据我所知,如果我将字段设置为=结果,那么我的ViewModel中的OnProperty方法应该正确吗?
[BroadcastReceiver(Enabled = true)]
[IntentFilter(new[] { "android.intent.action.bcr.newdata" })]
public class Receiver1 : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
Toast.MakeText(context, "Received intent!", ToastLength.Short).Show();
Services.StockService meh = new Services.StockService();
//MainViewModel md = new MainViewModel();
Dowork(meh, intent);
}
//this isnt correct i need to update viewmodel not call service direct!
private async void Dowork (Services.StockService meh, Intent intent)
{
string action = intent.Action.ToString();
string decodedBarcode = intent.GetStringExtra(BCRIntents.ExtraBcrString);
//now i just need to update my field in the xaml....somehow
}
}
// in your PCL
public interface IScanReceiver
{
}
// in your android project
public class Receiver1 : BroadcastReceiver, IScanReceiver
// in your viewmodel
MessagingCenter.Subscribe<IScanReceiver>();