LWUIT 1.4 - Why doesn't the virtual keyboard appear after first show during textfield edit? - java-me

I want to show the virtual keyboard when the user is editing the textfield. I take this approach :
public class ChpModif extends TextField {
public ChpModif(int maxChars, FocusListener focusListener, DataChangedListener dataChangeListener, VirtualKeyboard vkb)
{
super();
setReplaceMenu(false);
if (maxChars != -1)
setMaxSize(maxChars);
addFocusListener(focusListener);
addDataChangeListener(dataChangeListener);
if (vkb != null)
VirtualKeyboard.bindVirtualKeyboard(this, vkb);
}
protected Command installCommands(Command clear, Command t9)
{
return null;
}
}
public class ModifierFicheClient extends Ecran implements ActionListener, DataChangedListener, FocusListener
{
private VirtualKeyboard vkNombre = new VirtualKeyboard();
private String textFieldStatus, listBoxStatus;
private ListBox genretxt;
private boolean modifFromUpdate;
private ChpModif nomtxt,prenomtxt,cintxt,adressetxt/*,genretxt*/,lieutxt,professiontxt,courieltxt,teltxt,datenaisstxt;
private Component cursorItem;
...
public ModifierFicheClient(SmartPhoneBanking controller,String prosp_id,int recordStoreID,Form prevForm)
{
super("");
vkNombre.setInputModeOrder(new String[]{VirtualKeyboard.NUMBERS_SYMBOLS_MODE});
...
modifFromUpdate = false;
cintxt = new ChpModif(12, this, this, vkNombre);
...
}
public void dataChanged(int type, int index) {
textFieldStatus = "CHANGED";
if (!modifFromUpdate)
{
try
{
if (type == DataChangedListener.ADDED || type == DataChangedListener.CHANGED || type == DataChangedListener.REMOVED)
{
if (Display.getInstance().isVirtualKeyboardShowingSupported())
{
if (!Display.getInstance().isVirtualKeyboardShowing())
cursorItem.pointerReleased(cursorItem.getAbsoluteX(), cursorItem.getAbsoluteY());
}
}
}
catch (ClassCastException cce)
{}
}
}
public void focusGained(Component chp) {
cursorItem = chp;
}
public void focusLost(Component arg0) {
}
protected void onShowCompleted()
{
...
update();
}
public void update()
{
modifFromUpdate = true;
cintxt.setText(fichesignalitique.elementAt(0).toString());
...
modifFromUpdate = false;
}
...
}
The problem is that at the first time when I edit the textfield then the virtualkeyboard is shown ; then I click the Ok button of the virtualkeyboard , and then I edit again the textfield. But in this time the virtualkeyboard is not shown !
So how to make the virtualkeyboard shown everytime I edit the textfield ?

Its entirely possible that this is a 1.4 bug that was fixed in 1.5 since I can't see it right now. The VKB was brand new in 1.4 .

Related

How to detect recent button in android 8.1.0

I want to detect recent button but in android 8.1.0 it's not working.Below code is working on another version of android but in 8.1.0 the Intent.ACTION_CLOSE_SYSTEM_DIALOGS broadcast is not calling.I am using below implementation.
public class HomeWatcher {
static final String TAG = "hg";
private Context mContext;
private IntentFilter mFilter;
private OnHomePressedListener mListener;
private InnerRecevier mRecevier;
public HomeWatcher(Context context) {
mContext = context;
mFilter = new IntentFilter();
mFilter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
mFilter.addAction("");
}
public void setOnHomePressedListener(OnHomePressedListener listener) {
mListener = listener;
mRecevier = new InnerRecevier();
}
public void startWatch() {
if (mRecevier != null) {
mContext.registerReceiver(mRecevier, mFilter);
}
}
public void stopWatch() {
if (mRecevier != null) {
mContext.unregisterReceiver(mRecevier);
}
}
class InnerRecevier extends BroadcastReceiver {
final String SYSTEM_DIALOG_REASON_KEY = "reason";
final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
if (reason != null) {
Log.e(TAG, "action:" + action + ",reason:" + reason);
if (mListener != null) {
if (reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) {
mListener.onHomePressed();
} else if (reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
mListener.onHomeLongPressed();
}
}
}
}
}
}
}
and in class, I am calling using below code.
HomeWatcher mHomeWatcher = new HomeWatcher(this);
mHomeWatcher.startWatch();
Please help!.
Edited----
The above code is working properly in normal flow but when the screen pinning is set(ON) then it's not working. Even i am not getting any event like KeyUp, KeyDown
com.android.systemui package will be the foreground app when you click recent app button, so find the foreground running apps and launch your page if foreground running app is 'com.android.systemui'.
HomeWatcher mHomeWatcher = new HomeWatcher(this);
mHomeWatcher.setOnHomePressedListener(new OnHomePressedListener() {
#Override
public void onHomePressed() {
// do something here...
}
#Override
public void onHomeLongPressed() {
}
});
mHomeWatcher.startWatch();
For a detailed Answer Check
Detect Home And Recent App Button
Please use below code
`#Override
public boolean dispatchKeyEvent(KeyEvent event) {
Log.i("key pressed", String.valueOf(event.getKeyCode()));
return super.dispatchKeyEvent(event);
}`

Xamarin QLPreviewController + NavigationPage broken on iOS 10

After updating the device to iOS 10, QLPreviewController stopped to display correctly the documents. It shows the white screen.
I have extracted the sample scenario from the app.
It contains single page with two buttons that should load two different documents:
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:QuickLookIOS10Test"
x:Class="QuickLookIOS10Test.QuickLookIOS10TestPage">
<StackLayout Orientation="Vertical">
<Button Text="Load first doc" Clicked="OnLoadFirstClicked"/>
<Button Text="Load second doc" Clicked="OnLoadSecondClicked"/>
<Button Text="Navigate forward" Clicked="OnForwardClicked"/>
<local:QLDocumentView
x:Name="DocumentView"
BackgroundColor="Silver"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"/>
</StackLayout>
</ContentPage>
where:
public class QLDocumentView : View
{
public static readonly BindableProperty FilePathProperty =
BindableProperty.Create(nameof(FilePath), typeof(string), typeof(QLDocumentView), null);
public string FilePath
{
get { return (string)GetValue(FilePathProperty); }
set { SetValue(FilePathProperty, value); }
}
}
There is a custom renderer involved:
public class QLDocumentViewRenderer : ViewRenderer<QLDocumentView, UIView>
{
private QLPreviewController controller;
public override SizeRequest GetDesiredSize(double widthConstraint, double heightConstraint)
{
//This is a fix to prevent incorrect scaling after rotating from portrait to landscape.
//No idea why does this work :( Bug #101639
return new SizeRequest(Size.Zero, Size.Zero);
}
protected override void OnElementChanged(ElementChangedEventArgs<QLDocumentView> e)
{
base.OnElementChanged(e);
if (Control == null)
{
controller = new QLPreviewController();
SetNativeControl(controller.View);
}
RefreshView();
}
protected override void OnElementPropertyChanged(object sender,
System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == QLDocumentView.FilePathProperty.PropertyName)
{
RefreshView();
}
}
private void RefreshView()
{
DisposeDataSource();
if (Element?.FilePath != null)
{
controller.DataSource = new DocumentQLPreviewControllerDataSource(Element.FilePath);
}
controller.ReloadData();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
DisposeDataSource();
DisposeController();
}
}
private void DisposeDataSource()
{
var dataSource = controller.DataSource;
controller.DataSource = null;
dataSource?.Dispose();
}
private void DisposeController()
{
controller?.Dispose();
controller = null;
}
private class DocumentQLPreviewControllerDataSource : QLPreviewControllerDataSource
{
private readonly string fileName;
public DocumentQLPreviewControllerDataSource(string fileName)
{
this.fileName = fileName;
}
public override nint PreviewItemCount(QLPreviewController controller)
{
return 1;
}
public override IQLPreviewItem GetPreviewItem(QLPreviewController controller, nint index)
{
NSUrl url = NSUrl.FromFilename(fileName);
return new QlItem(url);
}
private sealed class QlItem : QLPreviewItem
{
private readonly NSUrl itemUrl;
public QlItem(NSUrl uri)
{
itemUrl = uri;
}
public override string ItemTitle { get { return string.Empty; } }
public override NSUrl ItemUrl { get { return itemUrl; } }
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
this.itemUrl?.Dispose();
}
}
}
}
}
If the application setups the main page like below:
MainPage = new NavigationPage(new QuickLookIOS10TestPage());
it does work on iOS 9.3 but not on iOS 10. If I remove NavigationPage:
MainPage = new QuickLookIOS10TestPage();
it works on both iOS versions.
The code behind for button clicks just sets the FilePath property of the control.
Sample app demonstrating the problem
Xamarin Forms 2.3.2.127
Xamarin Studio 6.1.1 (build 15)
I've faced with the same problem. It looks like something was changed or even broken in QuickLook in iOS10, but the solution is quite simple:
public class PdfViewerControlRenderer : ViewRenderer<PdfViewerControl, UIView>
{
private readonly bool IsOniOS10;
private UIViewController _controller;
private QLPreviewController _qlPreviewController;
public PdfViewerControlRenderer()
{
IsOniOS10 = UIDevice.CurrentDevice.CheckSystemVersion(10, 0);
}
protected override void OnElementChanged(ElementChangedEventArgs<PdfViewerControl> e)
{
if (e.NewElement != null)
{
_controller = new UIViewController();
_qlPreviewController = new QLPreviewController();
//...
// Set QuickLook datasource here
//...
if (!IsOniOS10)
{
_controller.AddChildViewController(_qlPreviewController);
_controller.View.AddSubview(_qlPreviewController.View);
_qlPreviewController.DidMoveToParentViewController(_controller);
}
SetNativeControl(_controller.View);
}
}
public override void LayoutSubviews()
{
base.LayoutSubviews();
_controller.View.Frame = Bounds;
_controller.View.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight;
_qlPreviewController.View.Frame = Bounds;
if (IsOniOS10)
{
_controller.View.AddSubview(_qlPreviewController.View);
_qlPreviewController.DidMoveToParentViewController(_controller);
}
}
}
Result:

XNA background music change not work properly

In XNA, i want to manage background sound for every game state. For example; StartMenu music will be playing when option is Start or Playing music will be playing when option is Playing. I arranged code as followed, as you can see i create play and stop method inside all sound class but it's only working while exiting to game.
public abstract class Sound
{
public SoundEffect Item { get; set; }
public Song BgSound { get; set; }
public abstract void LoadContent(ContentManager content);
public abstract void Play();
public abstract void Stop();
}
public class GameSound : Sound
{
public GameSound()
{
BgSound = null;
Item = null;
}
public override void LoadContent(ContentManager content)
{
BgSound = content.Load<Song>("Sounds/BgSound");
MediaPlayer.IsRepeating = true;
}
public override void Play()
{
MediaPlayer.Play(BgSound);
}
public override void Stop()
{
MediaPlayer.Stop();
}
}
public class StartUpSound : Sound
{
public StartUpSound()
{
BgSound = null;
Item = null;
}
public override void LoadContent(ContentManager content)
{
BgSound = content.Load<Song>("Sounds/StartUp");
MediaPlayer.IsRepeating = false;
}
public override void Play()
{
MediaPlayer.Play(BgSound);
}
public override void Stop()
{
MediaPlayer.Stop();
}
}
public class GameBase : Microsoft.Xna.Framework.Game
{
//..
GameSound gameSoundFx = new GameSound();
StartUpSound startUpSoundFx = new StartUpSound();
//..
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
gameSoundFx.LoadContent(Content);
startUpSoundFx.LoadContent(Content);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
if (currentState == GameState.StartMenu)
{
startUpSoundFx.Play();
}
if (currentState == GameState.Playing)
{
startUpSoundFx.Stop();
gameSoundFx.Play();
}
spriteBatch.End();
base.Draw(gameTime);
}
}
Edited
Also i tried again like this but nothing has changed;
if (currentState == GameState.StartMenu)
{
startUpSoundFx.BgSound = Content.Load<Song>("Sounds/StartUp");
MediaPlayer.Play(startUpSoundFx.BgSound);
}
if (currentState == GameState.Playing)
{
MediaPlayer.Stop();
gameSoundFx.BgSound = Content.Load<Song>("Sounds/StartUp");
MediaPlayer.Play(gameSoundFx.BgSound);
}
This has already been answered -
https://gamedev.stackexchange.com/questions/86038/c-how-to-properly-play-background-songs-in-xna
Please review the answer there, here's the example included -
switch (currentGameState)
{
case GameState.MainMenu:
if (musicState == MusicState.Playing && currentGameState != lastGameState)
{
MediaPlayer.Stop();
musicState = MusicState.NotPlaying;
}
if (musicState == MusicState.NotPlaying)
{
MediaPlayer.Play(song_mainTheme);
musicState = MusicState.Playing;
}
break;
case GameState.GamePlaying:
if (musicState == MusicState.Playing && currentGameState != lastGameState)
{
MediaPlayer.Stop();
musicState = MusicState.NotPlaying;
}
if (musicState == MusicState.NotPlaying)
{
MediaPlayer.Play(song_actionTheme);
musicState = MusicState.Playing;
}
break;
}
It shows extending the states to allow for proper use of the Mediaplayer - as stated in the comments of your question.

JavaFX: Custom traversing with key combinations

I have a table with one editing combobox and three editable text fields,
editable fields create like this:
public class EditingCell extends TableCell<Person, String> {
private TextField textField;
public EditingCell() {
}
#Override
public void startEdit() {
super.startEdit();
if (textField == null) {
createTextField();
}
setGraphic(textField);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
Platform.runLater(new Runnable() {
#Override
public void run() {
textField.requestFocus();
textField.selectAll();
}
});
}
#Override
public void cancelEdit() {
super.cancelEdit();
setText((String) getItem());
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
#Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (textField != null) {
textField.setText(getString());
}
setGraphic(textField);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
} else {
setText(getString());
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
}
}
private void createTextField() {
textField = new TextField(getString());
textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
textField.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent t) {
if (t.getCode() == KeyCode.ENTER) {
commitEdit(textField.getText());
} else if (t.getCode() == KeyCode.ESCAPE) {
cancelEdit();
} else if (t.getCode() == KeyCode.TAB) {
commitEdit(textField.getText());
TableColumn nextColumn = getNextColumn(!t.isShiftDown());
if (nextColumn != null) {
getTableView().edit(getTableRow().getIndex(), nextColumn);
}
}
}
});
textField.focusedProperty().addListener(new ChangeListener<Boolean>() {
#Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
if (!newValue && textField != null) {
commitEdit(textField.getText());
}
}
});
}
private String getString() {
return getItem() == null ? "" : getItem().toString();
}
/**
*
* #param forward true gets the column to the right, false the column to the left of the current column
* #return
*/
private TableColumn<Person, ?> getNextColumn(boolean forward) {
List<TableColumn<Person, ?>> columns = new ArrayList<>();
for (TableColumn<Person, ?> column : getTableView().getColumns()) {
columns.addAll(getLeaves(column));
}
//There is no other column that supports editing.
if (columns.size() < 2) {
return null;
}
int currentIndex = columns.indexOf(getTableColumn());
int nextIndex = currentIndex;
if (forward) {
nextIndex++;
if (nextIndex > columns.size() - 1) {
nextIndex = 0;
}
} else {
nextIndex--;
if (nextIndex < 0) {
nextIndex = columns.size() - 1;
}
}
return columns.get(nextIndex);
}
private List<TableColumn<Person, ?>> getLeaves(TableColumn<Person, ?> root) {
List<TableColumn<Person, ?>> columns = new ArrayList<>();
if (root.getColumns().isEmpty()) {
//We only want the leaves that are editable.
if (root.isEditable()) {
columns.add(root);
}
return columns;
} else {
for (TableColumn<Person, ?> column : root.getColumns()) {
columns.addAll(getLeaves(column));
}
return columns;
}
}
}
And editable combo column create like this:
public static void createEditingComboColumn(final TableColumn<DUMMY_PurchaseOrderLine, String> Column, final ObservableList<String>comboData, final ObservableList<DUMMY_PurchaseOrderLine> Pdata) {
Column.setCellFactory(new Callback<TableColumn<DUMMY_PurchaseOrderLine,String>,TableCell<DUMMY_PurchaseOrderLine,String>>(){
#Override
public TableCell<DUMMY_PurchaseOrderLine, String> call(TableColumn<DUMMY_PurchaseOrderLine, String> p) {
final TableCell<DUMMY_PurchaseOrderLine, String> cell = new TableCell<DUMMY_PurchaseOrderLine, String>(){
#Override
public void updateItem(String item, boolean empty) {
if(item!=null){
final ComboBox editableComboBox = new ComboBox(comboData);
editableComboBox.setEditable(true);
editableComboBox.setMaxWidth(Double.MAX_VALUE);
Platform.runLater(new Runnable() {
#Override
public void run() {
editableComboBox.requestFocus();
}
});
setGraphic(editableComboBox);
}
}
};
cell.addEventFilter(KeyEvent.KEY_PRESSED,new EventHandler<KeyEvent>(){
#Override
public void handle(KeyEvent t) {
activeRow = cell.getIndex();
if(t.getCode() == KeyCode.TAB||t.getCode() ==KeyCode.RIGHT){
cell.getTableView().edit(cell.getTableRow().getIndex(),cell.getTableView().getColumns().get(1) );
}
}
});
return cell;
}
});
}
Problem: when I press TAB/Right arrow key from any column work properly ,but when I press SHIFT+Tab /left arrow from second column focus goes out. How I focus first column (editing combo) from second column using keyboard?
Thanks....
The condition below in key event handler
if (t.getCode() == KeyCode.TAB)
will handle "TAB" + Any modifier, which means it will handle "Ctrl+TAB", "Alt+TAB", "Shift+Alt+TAB" etc. The same is true for "Right" key. So to handle the "TAB" alone only, the preferred way is to define KeyCodeCombination.
Your posted code is partial, not executable ie. not SSCCE. As I understand your problem lays in key event handling. Because of this I wrote a completely different code but demonstrates the explanation mentioned above. See example, and try to traverse forward with key combination different from "TAB" or "RIGHT". Try with "Ctrl+TAB" or "Alt+RIGHT". It will not work for them, as expected.
public class TraverseDemo extends Application {
#Override
public void start(Stage primaryStage) {
final TextField textField1 = new TextField();
final TextField textField2 = new TextField();
final TextField textField3 = new TextField();
// Diasble all traversals since we will manage them manually, for only textField2.
textField1.setFocusTraversable(false);
textField2.setFocusTraversable(false);
textField3.setFocusTraversable(false);
// Define key combinations for traversals.
final KeyCombination kcTab = KeyCodeCombination.valueOf("TAB");
final KeyCombination kcShiftTab = KeyCodeCombination.valueOf("Shift+TAB");
final KeyCombination kcRight = KeyCodeCombination.valueOf("RIGHT");
final KeyCombination kcLeft = KeyCodeCombination.valueOf("LEFT");
// Default initial focused textfield
requestFocus(textField2);
textField2.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent t) {
if (kcTab.match(t) || kcRight.match(t)) {
System.out.println("traverse forward");
requestFocus(textField3);
} else if (kcShiftTab.match(t) || kcLeft.match(t)) {
System.out.println("traverse backward");
requestFocus(textField1);
}
}
});
StackPane root = new StackPane();
root.getChildren().add(HBoxBuilder.create().spacing(10).children(textField1, textField2, textField3).build());
Scene scene = new Scene(root, 300, 150);
primaryStage.setScene(scene);
primaryStage.show();
}
private void requestFocus(final Node node) {
Platform.runLater(new Runnable() {
#Override
public void run() {
node.requestFocus();
}
});
}
public static void main(String[] args) {
launch(args);
}
}

How to reflect changes in viewmodel to tableviewcell view with binding in MVVMcross

Am a little stuck with getting changes reflected from the ViewModel to the View when used in a MvxBindableTableViewCell. I am using the vNext branch of MvvmCross on iOS.
Everything is set up properly and the initial values are visible when loading/showing the list for the first time. The list is a ObservableCollection<T> and the ViewModels inherit from MvxViewModel (thus implements INotifyPropertyChanged).
The main ViewModel looks like this:
public abstract class BaseViewModel : MvxViewModel, IMvxServiceConsumer
{
//... just regular implementation
}
public class UploadListViewModel: BaseViewModel
{
private readonly IUploadItemTasks uploadItemTasks;
private readonly IPhotoPickerService photoPickerService;
public IObservableCollection<UploadItemViewModel> Uploads { get { return this.LoadUploadItems(); } }
public UploadListViewModel()
{
this.uploadItemTasks = this.GetService<IUploadItemTasks>();
this.photoPickerService = this.GetService<IPhotoPickerService>();
}
private IObservableCollection<UploadItemViewModel> LoadUploadItems()
{
using (var unitOfWork = UnitOfWork.Start ())
{
return new SimpleObservableCollection<UploadItemViewModel>(uploadItemTasks.GetAll());
}
}
public void StartUpload ()
{
if (this.Uploads == null || this.Uploads.Count == 0) {
ReportError("Error", "No images to upload");
return;
}
this.Uploads.ForEach (uploadItem => PostCallback (uploadItem));
}
private void PostCallback (UploadItemViewModel uploadAsset)
{
IProgressReporter progressReporter = uploadAsset;
this.photoPickerService.GetAssetFullImage(uploadAsset.ImageUrl,
(image) => {
UIImage fullImage = image;
NSData jpeg = fullImage.AsJPEG();
byte[] jpegBytes = new byte[jpeg.Length];
System.Runtime.InteropServices.Marshal.Copy(jpeg.Bytes, jpegBytes, 0, Convert.ToInt32(jpeg.Length));
MemoryStream stream = new MemoryStream(jpegBytes);
Uri destinationUrl = new Uri(uploadAsset.DestinationUrl + "&name=" + uploadAsset.Name + "&contentType=image%2FJPEG");
//TO DO: Move this to plugin
var uploader = new Uploader().UploadPicture (destinationUrl, stream, UploadComplete, progressReporter);
uploader.Host = uploadAsset.Host;
ThreadPool.QueueUserWorkItem (delegate {
uploader.Upload ();
jpeg = null;
});
});
}
private void UploadComplete (string name)
{
if (name == null){
ReportError("Error","There was an error uploading the media.");
} else
{
//ReportError("Succes", name);
}
}
The item ViewModel looks like:
public interface IProgressReporter
{
float Progress { get; set;}
}
public abstract class BaseAssetViewModel: BaseViewModel, IBaseAssetViewModel
{
//... just regular properties
}
public class UploadItemViewModel: BaseAssetViewModel, IProgressReporter
{
public UploadItemViewModel(): base()
{
}
private float progress;
public float Progress {
get {
return this.progress;
}
set {
this.progress = value;
this.RaisePropertyChanged(() => Progress);
}
}
}
The View for the items inherits from MvxBindableTableViewCell and has the property:
private float progress;
public float ProgressMarker {
get {
return progress;
}
set {
progress = value;
// change progressbar or textfield here
}
}
The tableviewcell is bounded to the UploadItemViewModel via the BindingText:
public const string BindingText = #"ProgressMarker Progress, Converter=Float;";
The Uploader class mentioned in the snippet of UploadListViewModel implements a private method which tries to set the progress on the IProgressReporter.
float progressValue;
void SetProgress (float newvalue)
{
progressValue = newvalue;
this.dispatcher.InvokeOnMainThread (delegate {
if (ProgressReporter != null)
ProgressReporter.Progress = progressValue;
});
}
During the first viewing of the list I can see that the properties in both the ViewModel and View are being hit but when I update the ViewModel via the interface IProgressReporter with a new value in Progress the View in the tableviewcell is not updated nor the property is being called.
What am I doing wrong or what am I missing here?
UPDATE: Check the answer to this question.
I found why the binding didn't work. I was replacing the ObservableCollection over and over again.. I changed that piece of code as stated below and now it reflects the changes made to the UploadItemViewModel in the View of the cell.
private IObservableCollection<UploadItemViewModel> uploads;
private IObservableCollection<UploadItemViewModel> LoadUploadItems()
{
if (uploads == null)
{
using (var unitOfWork = UnitOfWork.Start ())
{
uploads = new SimpleObservableCollection<UploadItemViewModel>(uploadItemTasks.FindAll());
}
}
return uploads;
}

Resources