I've created a custom XAML Activity inherited from NativeActivity and IActivityTemplateFactory
The Designer shows the correct look and feel inside the Library I've defined.
However when I drop it on the Flow Surface of a workflow Console Application I don't see it rendered. The CPU pegs at 50% and if I run procmon.exe I see BUFFEROVERFLOW on the .XAML file and a NOT REPARSE error on the exe itself.
I do have the typeof Designer defined as the attribute of the class.
I've turned on Exceptions in the VS debug to see if an exception is being thrown but nothing ever comes out.
--CODE-- CS
[Designer(typeof(ITCRetryActivityDesigner))]
public sealed class ITCRetryActivity : NativeActivity, IActivityTemplateFactory
{
private static readonly TimeSpan DefaultRetryInterval = new TimeSpan(0, 0, 0, 1);
private readonly Variable<Int32> _attemptCount = new Variable<Int32>();
private readonly Variable<TimeSpan> _delayDuration = new Variable<TimeSpan>();
private readonly Delay _internalDelay;
public ITCRetryActivity()
{
_internalDelay = new Delay
{
Duration = new InArgument<TimeSpan>(_delayDuration)
};
Body = new ActivityAction();
MaxAttempts = 5;
ExceptionType = typeof(TimeoutException);
RetryInterval = DefaultRetryInterval;
}
[DebuggerNonUserCode]
public Activity Create(DependencyObject target)
{
return new ITCRetryActivity
{
Body =
{
Handler = new Sequence()
}
};
}
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
metadata.AddDelegate(Body);
metadata.AddImplementationChild(_internalDelay);
metadata.AddImplementationVariable(_attemptCount);
metadata.AddImplementationVariable(_delayDuration);
RuntimeArgument maxAttemptsArgument = new RuntimeArgument("MaxAttempts", typeof(Int32), ArgumentDirection.In, true);
RuntimeArgument retryIntervalArgument = new RuntimeArgument("RetryInterval", typeof(TimeSpan), ArgumentDirection.In, true);
metadata.Bind(MaxAttempts, maxAttemptsArgument);
metadata.Bind(RetryInterval, retryIntervalArgument);
Collection<RuntimeArgument> arguments = new Collection<RuntimeArgument>
{
maxAttemptsArgument,
retryIntervalArgument
};
metadata.SetArgumentsCollection(arguments);
ValidationError validationError;
if (Body == null)
{
validationError = new ValidationError("No Children are defined in this Retry Activity", true, "Body");
metadata.AddValidationError(validationError);
}
if (typeof (Exception).IsAssignableFrom(ExceptionType) != false) return;
validationError = new ValidationError("Exception type does not match", false, "ExceptionType");
metadata.AddValidationError(validationError);
}
protected override void Execute(NativeActivityContext context)
{
ExecuteAttempt(context);
}
private static Boolean ShouldRetryAction(Type exceptionType, Exception thrownException)
{
return exceptionType != null && exceptionType.IsInstanceOfType(thrownException);
}
private void ActionFailed(NativeActivityFaultContext faultcontext, Exception propagatedexception, ActivityInstance propagatedfrom)
{
Int32 currentAttemptCount = _attemptCount.Get(faultcontext);
currentAttemptCount++;
_attemptCount.Set(faultcontext, currentAttemptCount);
Int32 maxAttempts = MaxAttempts.Get(faultcontext);
if (currentAttemptCount >= maxAttempts)
{
// There are no further attempts to make
return;
}
if (ShouldRetryAction(ExceptionType, propagatedexception) == false)
{
return;
}
faultcontext.CancelChild(propagatedfrom);
faultcontext.HandleFault();
TimeSpan retryInterval = RetryInterval.Get(faultcontext);
if (retryInterval == TimeSpan.Zero)
{
ExecuteAttempt(faultcontext);
}
else
{
// We are going to wait before trying again
_delayDuration.Set(faultcontext, retryInterval);
faultcontext.ScheduleActivity(_internalDelay, DelayCompleted);
}
}
private void DelayCompleted(NativeActivityContext context, ActivityInstance completedinstance)
{
ExecuteAttempt(context);
}
private void ExecuteAttempt(NativeActivityContext context)
{
if (Body == null)
{
return;
}
context.ScheduleAction(Body, null, ActionFailed);
}
[Browsable(false)]
public ActivityAction Body
{
get;
set;
}
[DefaultValue(typeof(TimeoutException))]
public Type ExceptionType
{
get;
set;
}
public InArgument<Int32> MaxAttempts
{
get;
set;
}
public InArgument<TimeSpan> RetryInterval
{
get;
set;
}
}
}
--XAML--
<sap:ActivityDesigner x:Class="ITC.Common.Workflow.ITCRetryActivityDesigner"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sap="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation"
xmlns:sapv="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation"
xmlns:conv="clr-namespace:System.Activities.Presentation.Converters;assembly=System.Activities.Presentation">
<sap:ActivityDesigner.Icon>
<DrawingBrush>
<DrawingBrush.Drawing>
<ImageDrawing>
<ImageDrawing.Rect>
<Rect Location="0,0"
Size="16,16">
</Rect>
</ImageDrawing.Rect>
<ImageDrawing.ImageSource>
<BitmapImage UriSource="d-metal-reload-arrows.jpg"></BitmapImage>
</ImageDrawing.ImageSource>
</ImageDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</sap:ActivityDesigner.Icon>
<sap:ActivityDesigner.Resources>
<conv:ModelToObjectValueConverter x:Key="ModelItemConverter"
x:Uid="sadm:ModelToObjectValueConverter_1" />
<DataTemplate x:Key="Collapsed">
<TextBlock HorizontalAlignment="Center"
FontStyle="Italic"
Foreground="Gray">
Double-Click to View
</TextBlock>
</DataTemplate>
<DataTemplate x:Key="Expanded">
<StackPanel Orientation="Vertical">
<Grid Name="contentGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"
Grid.Column="0"
HorizontalAlignment="Left"
VerticalAlignment="Center">
Exception Type:
</TextBlock>
<sapv:TypePresenter HorizontalAlignment="Left"
VerticalAlignment="Center"
Margin="6"
Grid.Row="0"
Grid.Column="1"
Filter="ExceptionTypeFilter"
AllowNull="false"
BrowseTypeDirectly="false"
Label="Exception Type"
Type="{Binding Path=ModelItem.ExceptionType, Mode=TwoWay, Converter={StaticResource ModelItemConverter}}"
Context="{Binding Context}" />
</Grid>
<sap:WorkflowItemPresenter Item="{Binding ModelItem.Body.Handler}"
HintText="Drop Activity"
Margin="6" />
</StackPanel>
</DataTemplate>
<Style x:Key="ExpandOrCollapsedStyle"
TargetType="{x:Type ContentPresenter}">
<Setter Property="ContentTemplate"
Value="{DynamicResource Collapsed}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=ShowExpanded}"
Value="true">
<Setter Property="ContentTemplate"
Value="{DynamicResource Expanded}" />
</DataTrigger>
</Style.Triggers>
</Style>
</sap:ActivityDesigner.Resources>
<Grid>
<ContentPresenter Style="{DynamicResource ExpandOrCollapsedStyle}"
Content="{Binding}" Height="16" VerticalAlignment="Top" />
</Grid>
How can I debug this situation?
Thanks.
I resolved my issue by removing the Exception type as stated in comments and not having the icon graphic (using the default since it's not all that important.
Related
I have an ObservableCollection<List<Model>> Data in my ViewModel.
In my Page I need a CarouselView, in which each ItemTemplate shows the data of the Data list in a ListView.
Currently, I am doing that in that way:
<CarouselView ItemsSource="{Binding Data}">
<CarouselView.ItemTemplate>
<DataTemplate>
<StackLayout>
...
<ListView ItemsSource="{Binding .}">
...
</ListView>
</StackLayout>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
In the way I am doing that I get a "Specified cast not valid" exception, in which I see the following additional information:
{System.InvalidCastException: Specified cast is not valid.
at (wrapper castclass) System.Object.__castclass_with_cache(object,intptr,intptr)
at Xamarin.Forms.Internals.TemplatedItemsList`2[TView,TItem].ActivateContent (System.Int32 index, System.Object item) [0x00032]
in <62e3629c74b84e3d834046331d2bb5f8>:0
at Xamarin.Forms.Internals.TemplatedItemsList`2[TView,TItem].CreateContent (System.Int32 index, System.Object item, System.Boolean insert) [0x00000]
in <62e3629c74b84e3d834046331d2bb5f8>:0
at Xamarin.Forms.Internals.TemplatedItemsList`2[TView,TItem].GetOrCreateContent (System.Int32 index, System.Object item) [0x00023]
in <62e3629c74b84e3d834046331d2bb5f8>:0
at Xamarin.Forms.Internals.TemplatedItemsList`2[TView,TItem].get_Item (System.Int32 index) [0x0000e]
in <62e3629c74b84e3d834046331d2bb5f8>:0
at Xamarin.Forms.Platform.iOS.ListViewRenderer+ListViewDataSource.GetCellForPath (Foundation.NSIndexPath indexPath) [0x00007]
in D:\a\_work\1\s\Xamarin.Forms.Platform.iOS\Renderers\ListViewRenderer.cs:1397
at Xamarin.Forms.Platform.iOS.ListViewRenderer+ListViewDataSource.GetCell (UIKit.UITableView tableView, Foundation.NSIndexPath indexPath) [0x00021]
in D:\a\_work\1\s\Xamarin.Forms.Platform.iOS\Renderers\ListViewRenderer.cs:1105
at (wrapper managed-to-native) UIKit.UIApplication.UIApplicationMain(int,string[],intptr,intptr)
at UIKit.UIApplication.Main (System.String[] args, System.Type principalClass, System.Type delegateClass) [0x0003b]
in /Users/builder/azdo/_work/1/s/xamarin-macios/src/UIKit/UIApplication.cs:85
at App.iOS.Application.Main (System.String[] args) [0x00001]
in <Path>\Main.cs:18 }
The Model holds only string values, so the exception cannot come from this.
I'm not sure why you're getting that specific exception. I couldn't get the ListView inside of a CarouselView to work either.
However, it works when you use a bindable StackLayout instead of a ListView. My guess is that the bindable StackLayout doesn't support scrolling and thus doesn't fight with the CarouselView but I don't know.
MainPage, MainViewModel and items
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Xamarin.Forms;
namespace App1
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
}
public class MainViewModel
{
public ObservableCollection<Item> Data { get; }
public MainViewModel()
{
Data = new ObservableCollection<Item>(GenerateItems());
}
private IEnumerable<Item> GenerateItems()
{
return Enumerable.Range(1, 10)
.Select(a => new Item
{
ItemTitle = $"Item {a}",
SubItems = Enumerable.Range(1, 10).Select(b => new SubItem { SubItemTitle = $"SubItem {b}" }).ToList()
});
}
}
public class Item
{
public string ItemTitle { get; set; }
public List<SubItem> SubItems { get; set; }
}
public class SubItem
{
public string SubItemTitle { get; set; }
}
}
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
x:Class="App1.MainPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:App1">
<ContentPage.BindingContext>
<local:MainViewModel />
</ContentPage.BindingContext>
<CarouselView ItemsSource="{Binding Data}">
<CarouselView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Label Text="{Binding ItemTitle}" />
<StackLayout BindableLayout.ItemsSource="{Binding SubItems}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Label Text="{Binding SubItemTitle}" />
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</StackLayout>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
</ContentPage>
Result:
I've already asked about this topic, but this simple binding just don't want to work. My code first of all:
CItem.h
#pragma once
#include "pch.h"
namespace XamlApp
{
public ref class CItem sealed
{
public:
CItem(Platform::String^ Ho, Platform::String^ Ip, Platform::String^ Im);
Platform::String^ getHo();
Platform::String^ getIP();
property Platform::String^ Ho {
Platform::String^ get() { return this->ho; }
}
property Platform::String^ Ip {
Platform::String^ get() { return this->ip; }
}
property Platform::String^ Im {
Platform::String^ get() { return this->im; }
}
public:
private:
Platform::String^ ho;
Platform::String^ ip;
Platform::String^ im;
private:
};
}
CItem.cpp:
#include "pch.h"
#include "CItem.h"
CItem::CItem(Platform::String^ Ho, Platform::String^ Ip, Platform::String^ Im) :
ho{ Ho }, ip{ Ip }, im{ Im }
{
}
Platform::String^ CItem::getHo() {
return this->ho;
}
Platform::String^ CItem::getIP() {
return this->ip;
}
Main page:
Windows::UI::Xaml::Interop::IBindableVector^ test;
test = ref new Platform::Collections::Vector<CItem^>();
CItem^ dummy1 = ref new CItem(L"ho1",L"23323",L"Assets/ic_info.png");
CItem^ dummy2 = ref new CItem("ho2", "23323", "Assets/ic_info.png");
test->Append(dummy1);
test->Append(dummy2);
mainListView->ItemsSource = test;
MainPage.xaml:
<ListView x:Name="mainListView" HorizontalAlignment="Stretch" MaxWidth="500" VerticalAlignment="Center" Margin="20,0,20,-38" >
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Im}"/>
<TextBlock Text="{Binding Ho}"
Margin="20,0,20,8"
FontSize="24"
FontStyle="Italic"
FontWeight="SemiBold"
Foreground="DarkBlue"
/>
<TextBlock Text="{Binding Ip}"
Margin="20,0,20,8"
FontSize="24"
FontStyle="Italic"
FontWeight="SemiBold"
Foreground="DarkBlue"
/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
My Question is: What is wrong with this code? I actually get 2 listview-entries but not the data, they are just empty. I've already tried to change ho to Ho in xaml, I've already copied it step by step from the microsoft-sample.
In your initial implementation you need to add the BindableAttribute to your CItem class:
[Windows::UI::Xaml::Data::Bindable]
public ref class CItem sealed
Source: https://msdn.microsoft.com/en-us/magazine/dn166929.aspx
If you do this, the type of your vector does also not have to be
Windows::UI::Xaml::Interop::IBindableVector^ test;
You could simply use a
Platform::Collections::Vector<CItem^>^ test;
At least this worked for me!
After a while I figured out that it will work with this pattern alternatively, so I want to share my solution on this problem:
MainPage.xaml.c:
this->viewModel = ref new CItemViewModel();
MainPage.xaml.h:
public:
property CItemViewModel^ ViewModel
{
CItemViewModel^ get() { return this->viewModel; };
}
private:
CItemViewModel^ viewModel;
MainPage.xaml:
<ListView x:Name="mainListView" ItemsSource="{x:Bind ViewModel.CItems}" MaxHeight="230" Margin="20,0,20,-37" >
<ListView.ItemTemplate >
<DataTemplate x:DataType="local:CItem" >
<StackPanel Orientation="Horizontal">
<Image Source="{x:Bind Im}" Margin="10,0,0,5" Height="30" Width="30"/>
<TextBlock Margin="20,0,0,5" FontSize="12" >
<Run Text="{x:Bind Ho}" /><Run Text="{x:Bind Ip}"/>
</TextBlock>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
CItem stayed the same!
CItemViewModel.h:
public ref class CItemViewModel sealed {
public:
CItemViewModel();
property Windows::Foundation::Collections::IObservableVector<CItem^>^ CItems
{
Windows::Foundation::Collections::IObservableVector<CItem^>^ get()
{
if (this->cItems == nullptr)
{
this->cItems = ref new Platform::Collections::Vector<CItem^>();
}
return this->cItems;
};
}
private:
Windows::Foundation::Collections::IObservableVector<CItem^>^ cItems;
};
Hope it helps!
I have a list that is dynamically generated from the view.
when the button is clicked, a new row is added, the value is entered and saved.
.zul
<zk>
<window border="normal" title="hello" viewModel="#id('vm') #init('gemalto.CreateServiceVersion')" apply="org.zkoss.bind.BindComposer">
<grid id="demoGrid"
model="#load(vm.profileList) #template((each.editingStatus) ? 'editable' : 'noneditable')">
<columns sizable="true">
<column width="160px" >Value</column>
<column width="160px" ></column>
</columns>
<rows>
<template name="editable">
<row>
<textbox id="valueTextBox"
value="#load(each.serviceProfile.valueVariable) #save(each.serviceProfile.valueVariable, before='confirm')" />
<button
image="/img/save.png" label="save"
onClick="#command('confirm', currentVariable=each)"/>
</row>
</template>
<template name="noneditable">
<row>
<label value="#load(each.serviceProfile.valueVariable)" />
</row>
</template>
</rows>
</grid>
<div align="center">
<button label="Add" image="/img/create.png" onClick="#command('onAddNew')" />
</div>
</window>
</zk>
view model
public class CreateServiceVersion extends SelectorComposer<Component> {
private boolean isEditing = false;
private boolean displayEdit = true;
private boolean isAddNew = false;
private List<ServiceProfileStatus> profileList = new ArrayList<ServiceProfileStatus>();
public List<ServiceProfileStatus> getProfileList() {
return profileList;
}
#AfterCompose
public void afterCompose() {
profileList.add(new ServiceProfileStatus(new ServiceProfile("value1"), false));
profileList.add(new ServiceProfileStatus(new ServiceProfile("value2"), false));
}
#Command
public void CrudServiceVersion() {
Executions.sendRedirect("CrudServiceVersion.zul");
}
#Command
#NotifyChange({"profileList"})
public void onAddNew() {
if (!isEditing) {
ServiceProfileStatus sps = new ServiceProfileStatus(new ServiceProfile(""), displayEdit);
profileList.add(0, sps);
isAddNew = true;
isEditing = true;
}
}
#Command
public void confirm(#BindingParam("currentVariable") ServiceProfileStatus sps) {
isEditing = false;
isAddNew = false;
sps.setEditingStatus(isEditing);
BindUtils.postNotifyChange(null,null,sps,"*");
}
}
the problem is that I add a new item, the value is copied to all others items.
I put the images to see more clearly what is happening.
imgur.com/7u7OkPG
imgur.com/mf8PUYI
imgur.com/aJpNoXM
I tested with your code and it works normally with me.
Now I changed the code a little bit :
Removed the extends SelectorComposer from your viewmodel cause that is not needed for MVVM.
Changed your 2 templates to 1 template.
Usage of your boolean in your viewmodel in the zul.
Zul :
<?xml version="1.0" encoding="UTF-8"?>
<zk>
<window border="normal" title="hello" viewModel="#id('vm') #init('be.chillworld.CreateServiceVersion')" apply="org.zkoss.bind.BindComposer">
<grid id="demoGrid" model="#load(vm.profileList)">
<columns sizable="true">
<column width="160px" >Value</column>
<column width="160px" ></column>
</columns>
<rows>
<template name="model">
<row>
<textbox value="#load(each.serviceProfile.valueVariable) #save(each.serviceProfile.valueVariable, before='confirm')" />
<button disabled="#load(not each.editingStatus)" visible="#load(each.editingStatus)" image="/img/save.png" label="save"
onClick="#command('confirm', currentVariable=each)"/>
</row>
</template>
</rows>
</grid>
<div align="center">
<button disabled="#load(vm.mayCreateNew)" label="Add" image="/img/create.png" onClick="#command('onAddNew')" />
</div>
</window>
</zk>
Viewmodel :
package be.chillworld;
import java.util.ArrayList;
import java.util.List;
import org.zkoss.bind.BindUtils;
import org.zkoss.bind.annotation.AfterCompose;
import org.zkoss.bind.annotation.BindingParam;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zk.ui.Executions;
/**
*
* #author chillworld */
public class CreateServiceVersion {
private boolean isEditing = false;
private List<ServiceProfileStatus> profileList = new ArrayList<ServiceProfileStatus>();
public List<ServiceProfileStatus> getProfileList() {
return profileList;
}
#AfterCompose
public void afterCompose() {
profileList.add(new ServiceProfileStatus(new ServiceProfile("value1"), false));
profileList.add(new ServiceProfileStatus(new ServiceProfile("value2"), false));
}
#Command
public void CrudServiceVersion() {
Executions.sendRedirect("CrudServiceVersion.zul");
}
#Command
#NotifyChange({"profileList","mayCreateNew"})
public void onAddNew() {
isEditing = true;
ServiceProfileStatus sps = new ServiceProfileStatus(new ServiceProfile(""), true);
profileList.add(0, sps);
}
#Command
#NotifyChange("mayCreateNew")
public void confirm(#BindingParam("currentVariable") ServiceProfileStatus sps) {
isEditing = false;
sps.setEditingStatus(isEditing);
BindUtils.postNotifyChange(null, null, sps, "*");
}
public boolean getMayCreateNew() {
return isEditing;
}
}
ServiceProfileStatus.java :
package be.chillworld;
/**
*
* #author chillworld
*/
public class ServiceProfileStatus {
private ServiceProfile serviceProfile;
private boolean editingStatus;
public ServiceProfileStatus(ServiceProfile serviceProfile, boolean editingStatus) {
this.serviceProfile = serviceProfile;
this.editingStatus = editingStatus;
}
public boolean isEditingStatus() {
return editingStatus;
}
public void setEditingStatus(boolean editingStatus) {
this.editingStatus = editingStatus;
}
public ServiceProfile getServiceProfile() {
return serviceProfile;
}
public void setServiceProfile(ServiceProfile serviceProfile) {
this.serviceProfile = serviceProfile;
}
public ServiceProfileStatus(ServiceProfile serviceProfile) {
this.serviceProfile = serviceProfile;
}
}
ServiceProfile.java :
package be.chillworld;
/**
*
* #author chillworld
*/
public class ServiceProfile {
private String valueVariable;
public ServiceProfile(String valueVariable) {
this.valueVariable = valueVariable;
}
public String getValueVariable() {
return valueVariable;
}
public void setValueVariable(String valueVariable) {
this.valueVariable = valueVariable;
}
}
Glass GDK here. Trying to insert a livecard using remote views from service. I'm launching service via voice invocation. The voice command works, however it appears my service is not starting(no entries in log). Service is in android manifest. Below is code:
public class PatientLiveCardService extends Service {
private static final String LIVE_CARD_ID = "timer";
#Override
public void onCreate() {
Log.warn("oncreate");
super.onCreate();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
publishCard(this);
return START_STICKY;
}
#Override
public void onDestroy() {
unpublishCard(this);
super.onDestroy();
}
private void publishCard(Context context) {
Log.info("inserting live card");
if (mLiveCard == null) {
String cardId = "my_card";
TimelineManager tm = TimelineManager.from(context);
mLiveCard = tm.getLiveCard(cardId);
mLiveCard.setViews(new RemoteViews(context.getPackageName(),
R.layout.activity_vitals));
Intent intent = new Intent(context, MyActivity.class);
mLiveCard.setAction(PendingIntent
.getActivity(context, 0, intent, 0));
mLiveCard.publish();
} else {
// Card is already published.
return;
}
}
private void unpublishCard(Context context) {
if (mLiveCard != null) {
mLiveCard.unpublish();
mLiveCard = null;
}
}
}
Here is AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.INTERNET" >
</uses-permission>
<uses-permission android:name="android.permission.RECORD_AUDIO" >
</uses-permission>
<application
android:name="com.myApp"
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.myApp.MyActivity"
android:label="#string/app_name"
android:screenOrientation="landscape" >
</activity>
<service android:name="com.myApp.services.MyService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
</intent-filter>
<meta-data
android:name="com.google.android.glass.VoiceTrigger"
android:resource="#xml/voice_trigger_get_patient" />
</service>
</application>
This is a bug with XE11: the service is not started after the speech recognizer is complete.
As a workaround, you can have your voice trigger start an Activity which:
Processes the recognized speech in onResume.
Once the speech is processed, starts your Service with startService.
Calls finish to jump to the published LiveCard.
Love the new Implicit Data Templates, but I've just run into a problem with them.
My ComboBox is picking a DataTemplate which matches the ItemsSources type instead of following my DisplayMemberPath settings. Is there a way to tell the control to not look for DataTemplates?
<ComboBox DisplayMemberPath="DTO.Name" SelectedValue="{Binding DefaultModifierGroup, Mode=TwoWay}"
ItemsSource="{Binding MenuRepository.ModifierGroups, Source={StaticResource Locator}}"/>
I think you can't use DisplayMemberPath anymore. You probably need to created new data template inside that combobox.
<UserControl x:Class="SilverlightApplication1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:local="clr-namespace:SilverlightApplication1"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.Resources>
<DataTemplate DataType="local:Person">
<TextBlock Text="{Binding Address}" />
</DataTemplate>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel>
<ListBox ItemsSource="{Binding Items}" />
<ListBox ItemsSource="{Binding Items}" >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</Grid>
</UserControl>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace SilverlightApplication1 {
public partial class MainPage : UserControl {
public MainPage() {
this.DataContext = this;
InitializeComponent();
Items = new List<Person>{
new Person() { Name ="Name1", Address ="Address1" },
new Person() { Name ="Name2", Address ="Address2" },
new Person() { Name ="Name3", Address ="Address3" }
};
}
public IList<Person> Items { get; set; }
}
public class Person {
public string Name { get; set; }
public string Address { get; set; }
}
}