Viewmodellocater unregister Viewmodels - viewmodel

I'm already seeking all day for a solution. I'm a MVVM-beginner and I have the following problem.
This is the code of my viewmodelLocator:
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
if (ViewModelBase.IsInDesignModeStatic)
{
// Create design time view services and models
SimpleIoc.Default.Register<IDataService, DesignDataService>();
}
else
{
// Create run time view services and models
//SimpleIoc.Default.Register<IDataService,DataService>();
SimpleIoc.Default.Register<IDataService, OleDbDataService>();
}
SimpleIoc.Default.Register<A>();
SimpleIoc.Default.Register<B>();
}
public A a {
get { return ServiceLocator.Current.GetInstance<A>(); }
}
public B b {
get
{
return ServiceLocator.Current.GetInstance<B>();
}
}
After updating data from A, I want to open B and i do it in the following way:
private void A_Button_Click(object sender, RoutedEventArgs e)
{
var bWindow = new bView();
bWindow.Show();
this.Close();
}
This works, but B uses data from A, and the updated data is not shown until I close my program and open it again. I've read that it has something to do with the Viewmodellocator and messages but as I am rather new to this, I don't exactly now how and/or where I need to do some "cleaning up".
Can anyone please help me with this? Thanks in advance.

Related

How to prevent sharing files from "On My iPhone" folder

I have a xamarin forms app that can download files to "on my iphone" folder. But when I download a file on phone, I can go there and I can share it with another app.
But I want to prevent this. When I download a file from my app, I want the file not to be uploaded to another device from "on my iphone".
How to prevent this? Probably I can prevent this with mdm, but how?
Is there a way to prevent it with mdm managed app configuration. Some of my customers said that we can prevent this with the plist file in mdm. But I have very little information about mdm. How to do it with mdm?
I need a solution for ios and android. But especially for ios.
Thank you in advance.
Thank you for reply Jack.
I looked your sending thread and I tried it. But it didn't work for me.
I created MyUINavigationItem that is inherited from UINavigationItem. And I override SetRightBarButtonItem null. After I override UINavigationItem on PdfPreviewController that is inherited from QLPreviewController. And I set NavigationItem as MyUINavigationItem object. But it doesn't work for me. My codes is like these:
public class DocumentView : IDocumentView
{
void IDocumentView.DocumentView(string file, string title)
{
PdfPreviewController previewController = new PdfPreviewController();
if (File.Exists(file))
{
previewController.NavigationItem.SetRightBarButtonItem(null, false); //I tried this line as both comment and not comment but it didn't work
previewController.NavigationItem.SetRightBarButtonItems(null, false); //I tried this line as both comment and not comment but it didn't work
previewController.DataSource = new PDFPreviewControllerDataSource(NSUrl.FromFilename(file), title);
UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(previewController, true, null);
}
}
}
public class PdfPreviewController : QLPreviewController
{
MyUINavigationItem item = new MyUINavigationItem();
public override UINavigationItem NavigationItem => item;
}
public class MyUINavigationItem : UINavigationItem
{
public MyUINavigationItem()
{
}
public override void SetRightBarButtonItem(UIBarButtonItem item, bool animated)
{
//base.SetRightBarButtonItem(item, animated); //I tried this line as comment but it didn't work or
//base.SetRightBarButtonItem(null, animated); //I tried this line but it didn't work
}
public override void SetRightBarButtonItems(UIBarButtonItem[] items, bool animated)
{
//base.SetRightBarButtonItems(items, animated); //I tried this line as comment but it didn't work or
//base.SetRightBarButtonItems(null, animated); //I tried this line but it throwed exception
//base.SetRightBarButtonItems(new UIBarButtonItem[0], animated); //I tried this line but it didn't work
}
}
But after your suggestion I looked for enable or hide share button. And I could access child view controller of UINavigationController and I set RightBarButtonItem enable value false.
public class PdfPreviewController : QLPreviewController
{
public override void ViewDidAppear(bool animated)
{
try
{
ActionMenuControl();
}
catch (Exception ex)
{
}
}
public override void ViewDidLayoutSubviews()
{
try
{
ActionMenuControl();
}
catch (Exception ex)
{
}
}
public void ActionMenuControl()
{
try
{
if (this.ChildViewControllers.Length != 0)
{
var navigationController = this.ChildViewControllers.First() as UINavigationController;
if (navigationController.View.Subviews.Length != 0)
{
var layoutContainerView = navigationController.View.Subviews.FirstOrDefault(x => x is UINavigationBar) as UINavigationBar;
if (layoutContainerView != null)
{
if (layoutContainerView.Items.Length != 0)
{
var item = layoutContainerView.Items[0];
if (item.RightBarButtonItems.Length != 0)
item.RightBarButtonItem.Enabled = false;
}
}
}
var toolbar = navigationController.Toolbar;
if (toolbar != null)
{
if(toolbar.Items.Length != 0)
{
toolbar.Items[0].Enabled = false;
}
}
}
}
catch (Exception ex)
{
}
}
}
It works for right bar. But if opens mp3 files, share button appear on toolbar (on bottom) And I didn't access it. How can I do it for mp3 files? How to access toolbar? (Actually it doesn't work when opens and not move it. But if I open it and move it, it works (because it enters ViewDidLayoutSubviews events))
Sorry for long reply. But I wanted to tell about what I did. Because maybe I did missed something.

How to detect backspace in an Entry control when it is empty

I am using Xamarin.Forms with Android. I have a form which has 4 Entry controls for a user to enter code. I am using TextChanged event to detect user input and automatically move focus to the next control. This part works fine, i.e. as user types a digit focus automatically jumps to the next entry. However, I need to achieve the opposite, user should be able to tap backspace button and focus should move to the previous control. The problem is that TextChanged is not triggered when entry control is empty. How can I achieve this? Is there a custom renderer I can create for android to capture text input? Maybe there is a way to use 1 entry instead but I need to make it look like distinct 4 boxes.
Finally,I've found a solution for this by implementing a renderer in android.
In shared code(PCL),Create a class like this
public class CustomEntry:Entry
{
public delegate void BackspaceEventHandler(object sender, EventArgs e);
public event BackspaceEventHandler OnBackspace;
public CustomEntry()
{
}
public void OnBackspacePressed()
{
if (OnBackspace != null)
{
OnBackspace(null, null);
}
}
}
And,Then in your android project create a renderer like this:
public class CustomEntryRenderer: EntryRenderer
{
public override bool DispatchKeyEvent(KeyEvent e)
{
if (e.Action == KeyEventActions.Down)
{
if (e.KeyCode == Keycode.Del)
{
if (string.IsNullOrWhiteSpace(Control.Text))
{
var entry = (PasswordBox)Element;
entry.OnBackspacePressed();
}
}
}
return base.DispatchKeyEvent(e);
}
protected override void
OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
}
}
And then use it like this:
Entry1.OnBackspace += Entry1BackspaceEventHandler;
public void Entry1BackspaceEventHandler()
{
//things you want to do
}

Permanently hide the Task List window in Visual Studio 2017

I haven't been able to find an answer for this online, but basically I want to permanently hide the Task List window that pops up whenever I test a Biztalk map. Right now I've found a temp solution by minimizing the window as much as possible, so it doesnt get in the way, but it would be nice to get rid of it entirely.
This is the window in question.
Unfortunately, no (for clarity, the answer is no...unless you want to write an Shell Extension ;).
I'm often as frustrated by this as you but have found that simply tucking it away in a corner or along the status bar is just as good as hiding it.
I presume the activate action is baked into the map designer.
You can try the following extension for Visual Commander to automatically close the Task List window once it is displayed:
public class E : VisualCommanderExt.IExtension
{
public void SetSite(EnvDTE80.DTE2 DTE, Microsoft.VisualStudio.Shell.Package package)
{
events = DTE.Events;
windowEvents = events.WindowEvents;
windowEvents.WindowActivated += OnWindowActivated;
}
public void Close()
{
windowEvents.WindowActivated -= OnWindowActivated;
}
private void OnWindowActivated(EnvDTE.Window gotFocus, EnvDTE.Window lostFocus)
{
try
{
if (gotFocus.Caption == "Task List")
CloseWindow(gotFocus);
}
catch (System.Exception)
{
}
}
private void CloseWindow(EnvDTE.Window w)
{
System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke(
System.Windows.Threading.DispatcherPriority.Background,
new System.Action(() =>
{
try
{
w.Close();
}
catch (System.Exception)
{
}
}
));
}
private EnvDTE.Events events;
private EnvDTE.WindowEvents windowEvents;
}

Caliburn Micro Communication between ViewModels

hopefully you can help me. First of all, let me explain what my problem is.
I have two ViewModels. The first one has e.g. stored information in several textboxes.
For example
private static string _tbxCfgLogfile;
public string TbxCfgLogfile
{
get { return _tbxCfgLogfile; }
set
{
_tbxCfgLogfile = value;
NotifyOfPropertyChange(() => TbxCfgLogfile);
}
}
The other ViewModel has a Button where i want to save this data from the textboxes.
It does look like this
public bool CanBtnCfgSave
{
get
{
return (new PageConfigGeneralViewModel().TbxCfgLogfile.Length > 0 [...]);
}
}
public void BtnCfgSave()
{
new Functions.Config().SaveConfig();
}
How can i let "CanBtnCfgSave" know that the condition is met or not?
My first try was
private static string _tbxCfgLogfile;
public string TbxCfgLogfile
{
get { return _tbxCfgLogfile; }
set
{
_tbxCfgLogfile = value;
NotifyOfPropertyChange(() => TbxCfgLogfile);
NotifyOfPropertyChange(() => new ViewModels.OtherViewModel.CanBtnCfgSave);
}
}
It does not work. When i do remember right, i can get the data from each ViewModel, but i cannot set nor Notify them without any effort. Is that right? Do i have to use an "Event Aggregator" to accomplish my goal or is there an alternative easier way?
Not sure what you are doing in your viewmodels - why are you instantiating viewmodels in property accessors?
What is this line doing?
return (new PageConfigGeneralViewModel().TbxCfgLogfile.Length > 0 [...]);
I can't be sure from your setup as you haven't mentioned much about the architecture, but sincce you should have an instance of each viewmodel, there must be something conducting/managing the two (or one managing the other)
If you have one managing the other and you are implementing this via concrete references, you can just pick up the fields from the other viewmodel by accessing the properties directly, and hooking the PropertyChanged event of the child to notify the parent
class ParentViewModel : PropertyChangedBase
{
ChildViewModel childVM;
public ParentViewModel()
{
// Create child VM and hook up event...
childVM = new ChildViewModel();
childVM.PropertyChanged = ChildViewModel_PropertyChanged;
}
void ChildViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
// When any properties on the child VM change, update CanSave
NotifyOfPropertyChange(() => CanSave);
}
// Look at properties on the child VM
public bool CanSave { get { return childVM.SomeProperty != string.Empty; } }
public void Save() { // do stuff }
}
class ChildViewModel : PropertyChangedBase
{
private static string _someProperty;
public string SomeProperty
{
get { return _someProperty; }
set
{
_someProperty = value;
NotifyOfPropertyChange(() => SomeProperty);
}
}
}
Of course this is a very direct way to do it - you could just create a binding to CanSave on the child VM if that works, saving the need to create the CanSave property on the parent

LinqToSQL Can't Update Twice

I try to update twice with same data but it throw exception
public void UpdateOnSubmit<T>(T data) where T : class
{
lock (_lockObj)
{
using (DataModel dx = new DataModel(this._adapter.ConnectionString))
{
dx.GetTable<T>().Attach(data);
dx.Refresh(RefreshMode.KeepCurrentValues, data);
dx.SubmitChanges();
}
}
}
the exception is
An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext. This is not supported.
First update is success but not in second. Thanks in advance
Regards,
Brian
Okay seem like i've found the solution again. I Just set DeferredLoadingEnabled to false and it work like a charm.
public void UpdateOnSubmit<T>(T data) where T : class
{
lock (_lockObj)
{
using (DataModel dx = new DataModel(this._adapter.ConnectionString))
{
dx.DeferredLoadingEnabled = false;
dx.GetTable<T>().Attach(data);
dx.Refresh(RefreshMode.KeepCurrentValues, data);
dx.SubmitChanges();
}
}
}

Resources