Xamarin Forms - Get path of embedded file - path

I'm trying from hours/days to get a file which is placed into the PCL part
I saw some examples which using BaseURL but I want to make something cross platform and I can't found how to implement it onto UWP..
So I'm trying to get my local file's URL. For Images, I'm using ImageSource.FromResource("Gif.example.gif") but it doesn't work..
I also tried GifSource = new Uri(ImageSource.FromResource("Gif.example.gif").ToString()); but.. Nothing !
There is my custom control:
public class Gif : WebView
{
public static readonly BindableProperty GifSourceProperty =
BindableProperty.Create(nameof(Uri), typeof(string), typeof(Gif), null);
public string GifSource
{
get { return (string)GetValue(GifSourceProperty); }
set { SetValue(GifSourceProperty, value); }
}
Action<string> action;
public void RegisterAction(Action<string> callback)
{
action = callback;
}
public void Cleanup()
{
action = null;
}
public void InvokeAction(string data)
{
if (action == null || data == null)
{
return;
}
action.Invoke(data);
}
}
Thank for help !

To get the image from the PCL-project you must use the full path (with the namespace) to the image.
In your case: var src = ImageSource.FromResource("GifProject.Gif.example.gif");
And be sure that the "Build Action" of your file is set to "Embedded Resource".
You can extend this with reflection, when you don't want to provide the namespace directly.
You can find more infos on how to deal with embedded images on the xamarin developer page.

Related

xamarin.android webview evaluatejavascript It does not return any value at all

I have a fundamental problem that I can not really understand where the problem comes from.
I am designing a project by xamarin.android webview.
Now I need to run a Java function in Web View and check the return value in a if function.
I searched all the websites and in all of them I got the following code:
In Main Activity Class:
public class MainActivity : AppCompatActivity
{
WebView web_view;
.
.
.
Define web_view public in class
In OnCreate :
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.activity_main);
web_view = FindViewById<WebView>(Resource.Id.webview);
web_view.Settings.JavaScriptEnabled = true;
web_view.Settings.BuiltInZoomControls = true;
web_view.Settings.AllowContentAccess = true;
web_view.SetWebViewClient(new HelloWebViewClient());
web_view.LoadUrl("https://www.example.com");
}
In Back Key Press:
public override bool OnKeyDown(Android.Views.Keycode keyCode, Android.Views.KeyEvent e)
{
if (keyCode == Keycode.Back)
{
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Kitkat)
{
JavascriptResult jsr = new JavascriptResult();
string strjs = "closePackageDetails();";
web_view.EvaluateJavascript(strjs, jsr);
string rrr = jsr.strResult;
Toast.MakeText(this, "message send:" + rrr, ToastLength.Long).Show();
}
else
{
Toast.MakeText(this, "android version less 4.4" , ToastLength.Long).Show();
}
}
}
On JavascriptResult Class (separate on C# Class Palaced in MainActivity in Root directory)
namespace webviewapp
{
class JavascriptResult : Java.Lang.Object, IValueCallback
{
public string strResult;
public void OnReceiveValue(Java.Lang.Object result)
{
Toast.MakeText(Android.App.Application.Context, "رسیدن نتیجه احضار شد", ToastLength.Long);
strResult = ((Java.Lang.String)result).ToString();
}
}
}
<>
Everything looks right and the program is debugged without error and the APK file is created successfully.
After installing the program on the mobile phone and running it, the web page is loaded and everything looks good.
By touching the back button, the JavaScript function is executed correctly and the result is visible in Web View. But the result, which is a boolean value, is not returned.
In fact, the OnReceiveValue procedure does not work.
The variable 'rrr' always displays an null value.
Where it went wrong really puzzled me?
It is happening because the callback is executed later than the next line ,so the variable 'rrr' is always null.
Add the breakpoint at OnReceiveValue and the line string rrr = jsr.strResult; to check it .
Just do the next thing directly in the method OnReceiveValue in the callback class.

Dynamically changing the localization of an app using Avalonia and resource-files is not working

Intro
I'm working on an application and I want to be able to change the language when the app is running. For cross-platform compatibility I'm using AvaloniaUI.
I've found a few helpful articles:
Simple localization in WPF
Simple localization in WPF, extended for multiple resource-files
Answer to question on StackOverflow (basically the first link)
The problem
On startup of the app a binding is created (in LocExtensionWithMultipleResxFiles) between my control on the view and string this[string key] ( in TranslationSourceWithMultipleResxFiles). The app correctly loads the translations on startup.
On my View I have a button, the ClickEvent correctly sets TranslationSourceWithMultipleResxFiles.Instance.CurrentCulture but the text in my view doesn't update. I'm not sure where I did something wrong or if I need to change the code somewhere, so any help is appreciated.
My code
Using the above articles I have the following code:
TranslationSourceWithMultipleResxFiles contains a Dictionary for all the ResourceManagers that are used. string this[string key] returns the translated text. CurrentCulture is the property you set to change the Culture.
public class TranslationSourceWithMultipleResxFiles : INotifyPropertyChanged
{
public static TranslationSourceWithMultipleResxFiles Instance { get; } = new TranslationSourceWithMultipleResxFiles();
private readonly Dictionary<string, ResourceManager> resourceManagerDictionary = new Dictionary<string, ResourceManager>();
// key is the baseName + stringName that is binded to, this returns the translated text.
public string this[string key]
{
get
{
var (baseName, stringName) = SplitName(key);
string? translation = null;
if (resourceManagerDictionary.ContainsKey(baseName))
translation = resourceManagerDictionary[baseName].GetString(stringName, currentCulture);
return translation ?? key;
}
}
// the culture TranslationSourceWithMultipleResxFiles uses for translations.
private CultureInfo currentCulture = CultureInfo.InstalledUICulture;
public CultureInfo CurrentCulture
{
get { return currentCulture; }
set
{
if (currentCulture != value)
{
currentCulture = value;
NotifyPropertyChanged(string.Empty); // string.Empty/null indicates that all properties have changed
}
}
}
// WPF bindings register PropertyChanged event if the object supports it and update themselves when it is raised
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public void AddResourceManager(ResourceManager resourceManager)
{
if (!resourceManagerDictionary.ContainsKey(resourceManager.BaseName))
resourceManagerDictionary.Add(resourceManager.BaseName, resourceManager);
}
public static (string baseName, string stringName) SplitName(string name)
{
int idx = name.LastIndexOf('.');
return (name.Substring(0, idx), name.Substring(idx + 1));
}
}
In xaml you set the Translation.ResourceManager per UserContorl/Window etc. This is used so multiple resource files can be used in the application. Each child Control looks to this ResourceManager for their translations.
public class Translation : AvaloniaObject
{
public static readonly AttachedProperty<ResourceManager> ResourceManagerProperty = AvaloniaProperty.RegisterAttached<Translation, AvaloniaObject, ResourceManager>("ResourceManager");
public static ResourceManager GetResourceManager(AvaloniaObject dependencyObject)
{
return (ResourceManager)dependencyObject.GetValue(ResourceManagerProperty);
}
public static void SetResourceManager(AvaloniaObject dependencyObject, ResourceManager value)
{
dependencyObject.SetValue(ResourceManagerProperty, value);
}
}
Creates a Binding between the Control on the view and the correct ResourceManager.
public class LocExtensionWithMultipleResxFiles : MarkupExtension
{
public string StringName { get; } // Key name of the translation in a resource file.
public LocExtensionWithMultipleResxFiles(string stringName)
{
StringName = stringName;
}
// Find out what ResourceManager this control uses
private ResourceManager? GetResourceManager(object control)
{
if (control is AvaloniaObject dependencyObject)
{
object localValue = dependencyObject.GetValue(Translation.ResourceManagerProperty);
if (localValue != AvaloniaProperty.UnsetValue)
{
if (localValue is ResourceManager resourceManager)
{
TranslationSourceWithMultipleResxFiles.Instance.AddResourceManager(resourceManager);
return resourceManager;
}
}
}
return null;
}
// Create a binding between the Control and the translated text in a resource file.
public override object ProvideValue(IServiceProvider serviceProvider)
{
object? targetObject = (serviceProvider as IProvideValueTarget)?.TargetObject;
if (targetObject?.GetType().Name == "SharedDp") // is extension used in a control template?
return targetObject; // required for template re-binding
string baseName = GetResourceManager(targetObject)?.BaseName ?? string.Empty; // if the targetObject has a ResourceManager set, BaseName is set
if (string.IsNullOrEmpty(baseName)) // if the targetobjest doesnt have a RM set, it gets the root elements RM.
{
// rootObject is the root control of the visual tree (the top parent of targetObject)
object? rootObject = (serviceProvider as IRootObjectProvider)?.RootObject;
baseName = GetResourceManager(rootObject)?.BaseName ?? string.Empty;
}
if (string.IsNullOrEmpty(baseName)) // template re-binding
{
if (targetObject is Control frameworkElement)
baseName = GetResourceManager(frameworkElement.TemplatedParent)?.BaseName ?? string.Empty;
}
// create a binding between the Control and the correct resource-file
var binding = new ReflectionBindingExtension
{
Mode = BindingMode.OneWay,
Path = $"[{baseName}.{StringName}]", // This is the ResourceManager.Key
Source = TranslationSourceWithMultipleResxFiles.Instance,
FallbackValue = "Fallback, can't set translation.",
TargetNullValue = StringName,
};
return binding.ProvideValue(serviceProvider);
}
}
My View
<Window <!-- Standard Window xaml -->
xmlns:l="clr-namespace:TestAppForMVVMwithBaseClasses.Localization"
l:Translation.ResourceManager="{x:Static p:Resources.ResourceManager}">
<StackPanel>
<TextBlock Text="{l:LocExtensionWithMultipleResxFiles String1}"/>
<Button Content="Nl" Click="CurrentCultureNl_Click"/>
<Button Content="En" Click="CurrentCultureEn_Click"/>
</StackPanel>
</Window>

MvvmLight unable to create a controller for key

I am designing a cross platform application architecture using Xamarin iOS and Xamarin Android I decided to go with MvvmLight, it looks descent and is not hiding everything from the MVVM pattern, good and flexible.
While everything started to make sense trying to set it up and learn how to use it, I find myself difficult to understand why I get the following error.
Unable to create a controller for key ChartsPage
The setup.
In a PCL I have my ViewModels. I have a ViewModelLocator setup. I use the mvvmlightlibs Nuget Package.
public class ViewModelLocator
{
public static readonly string SchedulerPageKey = #"SchedulerPage";
public static readonly string ChartsPageKey = #"ChartsPage";
[SuppressMessage("Microsoft.Performance",
"CA1822:MarkMembersAsStatic",
Justification = "This non-static member is needed for data binding purposes.")]
public SchedulerViewModel Scheduler
{
get
{
return ServiceLocator.Current.GetInstance<SchedulerViewModel>();
}
}
public BizchartsViewModel Bizcharts
{
get
{
return ServiceLocator.Current.GetInstance<BizchartsViewModel>();
}
}
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
if (ViewModelBase.IsInDesignModeStatic)
{
// Haven't declared something yet
}
else
{
// Haven't declared something yet
}
SimpleIoc.Default.Register<SchedulerViewModel>();
SimpleIoc.Default.Register<BizchartsViewModel>();
}
}
The I have a unified iOS application using universal storyboard with size classes which has an initial UINavigationViewController SchedulerViewController and in the ViewDidLoad method I test the navigation to BizchartsViewController with 3 seconds delay. After 3 seconds I get the exceptions.
In the AppDelegate.
private static ViewModelLocator _locator;
public static ViewModelLocator Locator
{
get
{
if (_locator == null)
{
SimpleIoc.Default.Register<IDialogService, DialogService>();
_locator = new ViewModelLocator();
}
return _locator;
}
}
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
var nav = new NavigationService();
nav.Initialize((UINavigationController)Window.RootViewController);
nav.Configure(ViewModelLocator.ChartsPageKey, typeof(BizchartsViewController));
SimpleIoc.Default.Register<INavigationService>(() => nav);
return true;
}
The SchedulerViewController.
partial class SchedulerViewController : UIViewController
{
public SchedulerViewModel Vm {
get;
private set;
}
public SchedulerViewController (IntPtr handle) : base (handle)
{
Vm = AppDelegate.Locator.Scheduler;
}
public async override void ViewDidLoad ()
{
base.ViewDidLoad ();
await Task.Delay (3000);
Vm.NavigateToCharts ();
}
}
The SchedulerViewModel.
public class SchedulerViewModel : ViewModelBase
{
public void NavigateToCharts()
{
var nav = ServiceLocator.Current.GetInstance<INavigationService>();
nav.NavigateTo(ViewModelLocator.ChartsPageKey);
}
}
I definitely miss a detail somewhere!!!
If you follow carefully the blog post here, it says that with Storyboard you should use the string overload and not the typeof() in nav.Configure(Key, ViewController) and always set the storyboardId and restorationId in the Storyboard ViewController.
Note that because we are using a Storyboard, you must make sure to use
the Configure(string, string) overload, and NOT the Configure(string,
Type) one.

PowerDesigner addin develop

Anyone knows how to develop an add-in for PowerDesigner? I was reading the document of PowerDesigner about how to create an ActiveX Add-in, it says "The ActiveX must implement a specific interface called IPDAddIn to become a PowerDesigner add-in.". But I don't know where the interface IPDAddIn is, and how to implement it ?
Here is the online document
I have this old example, which could give some ideas, even if not everything it up-to-date.
using PdAddInTypLib;
namespace MineSpace
{
[ComVisible(true)]
[Guid("A6FA0D26-77E8-4DD3-B27E-F4050C3D5188")]
public class Launcher : IPdAddIn {
// Main() manages the console or GUI interface
// the PdAddIn interface is managed by an instance of Launcher
[ComVisible(false)]
[STAThread]
public static void Main(String[] args) {
}
public Launcher() {
_app = null;
}
// IPdAddIn implementation
public void Initialize(Object anApplication) {
try {
_app = (PdCommon.Application)anApplication;
}
catch (Exception e) {
// process
}
}
public void Uninitialize() {
}
public String ProvideMenuItems(String aMenu, Object anObj) {
return "";
}
public int IsCommandSupported(String aMenu, Object anObj, String aCommand) {
return 0;
}
public void DoCommand(String aMenu, Object anObj, String aCommand) {
}
private PdCommon.Application _app;
}
}
with the corresponding part in the class declaration:
[HKEY_CLASSES_ROOT\MyPlugin.Launcher]
#="MyPlugin.Launcher"
[HKEY_CLASSES_ROOT\MyPlugin.Launcher\CLSID]
#="{13749EFC-1ADA-4451-8C47-FF0B545FF172}"
[HKEY_CLASSES_ROOT\CLSID\{13749EFC-1ADA-4451-8C47-FF0B545FF172}]
#="MyPlugin.Launcher"
[HKEY_CLASSES_ROOT\CLSID\{13749EFC-1ADA-4451-8C47-FF0B545FF172}\InprocServer32]
#="C:\windows\System32\mscoree.dll"
"ThreadingModel"="Both"
"Class"="MyPlugin.Launcher"
"Assembly"="MyPlugin, Version=1.0.1402.33688, Culture=neutral, PublicKeyToken=null"
"RuntimeVersion"="v1.0.3705"
[HKEY_CLASSES_ROOT\CLSID\{13749EFC-1ADA-4451-8C47-FF0B545FF172}\ProgId]
#="MyPlugin.Launcher"
[HKEY_CLASSES_ROOT\CLSID\{13749EFC-1ADA-4451-8C47-FF0B545FF172}\Implemented Categories\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}]
And the corresponding code to declare the add-in in PowerDesigner. If the File value is present, PowerDesigner could call DllRegisterServer on it, if the component is not yet registered.
[HKEY_LOCAL_MACHINE\SOFTWARE\Sybase\PowerDesigner 10\Addins\MyPlugin Launcher]
"Enable"="No"
"Class"="MyPlugin.Launcher"
"Type"="ActiveX"
"File"="d:\\myplugin\\myplugin.exe"

Sharepoint 2007 - cant find my modifications to web.config in SpWebApplication.WebConfigModifications

I cant seem to find the modifications I made to web.config in my FeatureRecievers Activated event. I try to get the modifications from the SpWebApplication.WebConfigModifications collection in the deactivate event, but this is always empty.... And the strangest thing is that my changes are still reverted after deactivating the feature...
My question is, should I not be able to view all changes made to the web.config files when accessing the SpWebApplication.WebConfigModifications collection in the Deactivating event? How should I go about to remove my changes explicitly?
public class FeatureReciever : SPFeatureReceiver
{
private const string FEATURE_NAME = "HelloWorld";
private class Modification
{
public string Name;
public string XPath;
public string Value;
public SPWebConfigModification.SPWebConfigModificationType ModificationType;
public bool createOnly;
public Modification(string name, string xPath, string value, SPWebConfigModification.SPWebConfigModificationType modificationType, bool createOnly)
{
Name = name;
XPath = xPath;
Value = value;
ModificationType = modificationType;
this.createOnly = createOnly;
}
}
private Modification[] modifications =
{
new Modification("connectionStrings", "configuration", "<connectionStrings/>", SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode, true),
new Modification("add[#name='ConnectionString'][#connectionString='Data Source=serverName;Initial Catalog=DBName;User Id=UserId;Password=Pass']", "configuration/connectionStrings", "<add name='ConnectionString' connectionString='Data Source=serverName;Initial Catalog=DBName;User Id=UserId;Password=Pass'/>", SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode, false)
};
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPSite siteCollection = (properties.Feature.Parent as SPWeb).Site as SPSite;
SPWebApplication webApplication = siteCollection.WebApplication;
siteCollection.RootWeb.Title = "Set from activating code at " + DateTime.Now.ToString();
foreach (Modification entry in modifications)
{
SPWebConfigModification webConfigModification = CreateModification(entry);
webApplication.WebConfigModifications.Add(webConfigModification);
}
webApplication.Farm.Services.GetValue<SPWebService>().ApplyWebConfigModifications();
webApplication.WebService.Update();
}
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
SPSite siteCollection = (properties.Feature.Parent as SPWeb).Site as SPSite;
SPWebApplication webApplication = siteCollection.WebApplication;
siteCollection.RootWeb.Title = "Set from deactivating code at " + DateTime.Now.ToString();
IList<SPWebConfigModification> modifications = webApplication.WebConfigModifications;
foreach (SPWebConfigModification modification in modifications)
{
if (modification.Owner == FEATURE_NAME)
{
webApplication.WebConfigModifications.Remove(modification);
}
}
webApplication.Farm.Services.GetValue<SPWebService>().ApplyWebConfigModifications();
webApplication.WebService.Update();
}
public override void FeatureInstalled(SPFeatureReceiverProperties properties)
{
}
public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
{
}
private SPWebConfigModification CreateModification(Modification entry)
{
SPWebConfigModification spWebConfigModification = new SPWebConfigModification()
{
Name = entry.Name,
Path = entry.XPath,
Owner = FEATURE_NAME,
Sequence = 0,
Type = entry.ModificationType,
Value = entry.Value
};
return spWebConfigModification;
}
}
Thanks for your time.
/Hans
Finally today I figured out what was wrong with my code (that is why the WebConfigModifications collection was empty when i queryied it in the deactivate event) it seems you must apply the changes in a different manner than I had done.
My original approach to applying the changes involved the following code:
Activate event
webApplication.Farm.Services.GetValue().ApplyWebConfigModifications();
webApplication.WebService.Update();
The "correct" way of doing it is this:
SPWebService.ContentService.ApplyWebConfigModifications();
webApplication.Update();
Although I am still at a loss why my original code did not work.. could someone with more knowlege of the configuration object in Sharepoint enlighten me?

Resources