Xamarin ios share extension get image - xamarin.forms

I created demo application with Xamarin.Forms (5.X.X)
And i created share extension. Everything is good until here.
I want to get image from share extension but i cant get.
I tried almost everything.
public class CustomShareViewController: SLComposeServiceViewController
{
public CustomShareViewController(IntPtr handle) : base(handle)
{
}
public override void DidReceiveMemoryWarning()
{
// Releases the view if it doesn't have a superview.
base.DidReceiveMemoryWarning();
// Release any cached data, images, etc that aren't in use.
}
public override async void ViewDidLoad()
{
base.ViewDidLoad();
string urlstr = string.Empty;
NSExtensionItem item = ExtensionContext.InputItems[0];
var itemProvider = item.Attachments[0];
var type = itemProvider.Description.Split('"');
if (itemProvider.HasItemConformingTo(type[1]))
{
var load = await itemProvider.LoadItemAsync(type[1], null);
NSUrl newUrl = (NSUrl)load;
urlstr = newUrl.FilePathUrl.ToString();
}
if (!Xamarin.Forms.Forms.IsInitialized)
Xamarin.Forms.Forms.Init();
// Create an instance of XF page with associated View Model
var xfPage = new ShareMainPage();
var viewModel = (ShareMainPageViewModel)xfPage.BindingContext;
viewModel.Message = urlstr;
viewModel.Image = urlstr;
//viewModel.BindableImage = ImageSource.FromStream(() => new MemoryStream(byteArray));
// Override the behavior to complete the execution of the Extension when a user press the button
viewModel.DoCommand = new Command(() => DoneClicked());
// Convert XF page to a native UIViewController which can be consumed by the iOS Extension
var newController = xfPage.CreateViewController();
// Make sure the presentation style is set to full screen to avoid rendering the original entry point
newController.ModalPresentationStyle = UIModalPresentationStyle.FormSheet;
// Present new view controller as a regular view controller
this.PresentModalViewController(newController, false);
//var someController = this.Storyboard.InstantiateViewController("SomeController") as SomeViewController;
//NavigationController.PushViewController(someController, true);
//var itemProvider = inputItem?.Attachments?[0] as NSItemProvider;
//if (itemProvider.HasItemConformingTo("public.url"))
//{
// itemProvider.LoadPreviewImage(null, (item, error) => {
// if (item is UIImage)
// {
// var image = item as UIImage;
// var data = image.AsPNG();
// ImageView.Image = UIImage.LoadFromData(data);
// }
// });
//}
}
public override bool ShouldInteractWithUrl(UITextView textView, NSUrl url, NSRange characterRange, UITextItemInteraction interaction)
{
return base.ShouldInteractWithUrl(textView, url, characterRange, interaction);
}
public override bool IsContentValid()
{
// Do validation of contentText and/or NSExtensionContext attachments here
return true;
}
public override void DidSelectPost()
{
// This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments.
// Inform the host that we're done, so it un-blocks its UI. Note: Alternatively you could call super's -didSelectPost, which will similarly complete the extension context.
}
public override void PresentationAnimationDidFinish()
{
base.PresentationAnimationDidFinish();
}
private void DoneClicked()
{
// Return any edited content to the host app.
// This template doesn't do anything, so we just echo the passed-in items.
ExtensionContext.CompleteRequest(ExtensionContext.InputItems, null);
}
private void WriteToDebugFile(string dbgText)
{
var documents = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var filename = Path.Combine(documents, "Share-Extension-Debug.txt");
if (!File.Exists(filename))
{
File.WriteAllText(filename, $"\n{DateTime.Now} - {dbgText}");
}
else
{
File.AppendAllText(filename, $"\n{DateTime.Now} - {dbgText}");
}
}
}
I tried two ways.
Bind file path and get from there. ImageResource.FromFile(...) but it doesnt work.
Bind stream and it doesnt work too.
My sharepage.xml is
<?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:Demo.ViewModels"
x:DataType="local:ShareMainPageViewModel"
xmlns:converters="clr-namespace:LifeApp.Mobile.Converters"
BackgroundColor="Green"
x:Class="LifeApp.Mobile.Views.ShareMainPage">
<ContentPage.BindingContext>
<local:ShareMainPageViewModel Message="Hello from Xamarin.Forms!" />
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout HorizontalOptions="Center" VerticalOptions="Center">
<Image Source="{Binding BindableImage}"
VerticalOptions="Start"
HorizontalOptions="CenterAndExpand" WidthRequest="200" HeightRequest="150"/>
<Label Text="{Binding Message}" TextColor="Black" FontSize="Medium" VerticalTextAlignment="Center"/>
<Button Command="{Binding DoCommand}" Text="Do the jungle!" TextColor="Black" />
</StackLayout>
</ContentPage.Content>
And SharePageViewModel
using System;
using System.ComponentModel;
using System.IO;
using System.Windows.Input;
using Xamarin.Essentials;
using Xamarin.Forms;
using Xamarin.Forms.Shapes;
namespace Demo.ViewModels
{
public class ShareMainPageViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _message;
public string Message
{
get { return _message; }
set
{
if (_message != value)
{
_message = value;
PropertyChanged?.Invoke(this, new
PropertyChangedEventArgs(nameof(Message)));
}
}
}
private string _image;
public string Image
{
get { return _image; }
set
{
if (_image != value)
{
_image = value;
PropertyChanged?.Invoke(this, new
PropertyChangedEventArgs(nameof(Image)));
}
}
}
public ImageSource _bindableImage { get; set; }
public ImageSource BindableImage
{
get
{
return _bindableImage;
}
set
{
if (_bindableImage !=null)
{
_bindableImage = value;
PropertyChanged?.Invoke(this, new
PropertyChangedEventArgs(nameof(BindableImage)));
}
}
}
private ICommand _doCommand;
public ICommand DoCommand
{
get { return _doCommand; }
set
{
if (_doCommand != value)
{
_doCommand = value;
PropertyChanged?.Invoke(this, new
PropertyChangedEventArgs(nameof(DoCommand)));
}
}
}
public ShareMainPageViewModel()
{
DoCommand = new Command(OnDoCommandExecuted);
}
private void OnDoCommandExecuted(object state)
{
// Acr.UserDialogs.UserDialogs.Instance.Alert("Completed");
Message = $"Job {Environment.TickCount} has been completed!";
}
}
}
I can get image file path but i cant bind and show image
file:///Users/xxxx/Library/Developer/CoreSimulator/Devices/58453DF3-58CF-4591-AC91-6A096FD7B814/data/Containers/Data/Application/1466F475-0F58-4F94-8511-B0BD9FE86DCA/tmp/WKFileShare-FbFp8eSD/adcf0796-2088-4d85-9420-c1d58c15cca4/....JPG
How can i solve this problem.

Related

How to update label in Xamarin Forms

Beginner here.
I'm trying to get the exact time, when this operation was executed successfully and print it on label. The problem is that when I click the button, the label doesn't update the text.
namespace HGB.Droid.Helpers
{
public class CallServiceHelper : ICallServiceHelper
{
IContactsHelper contactsHelper = DependencyService.Get<IContactsHelper>();
List<Repository> ObjContactList = new List<Repository>();
LabelModel labelModel = new LabelModel();
Context context = Android.App.Application.Context;
HttpClient client = new HttpClient();
public async Task UpdatePhonebook()
{
if (NetworkCheck.IsInternet())
{
var response = await client.GetAsync("http://mmmmmmmmmmm.aspx");
if (response.IsSuccessStatusCode)
{
string contactsJson = await response.Content.ReadAsStringAsync();
var list = JsonConvert.DeserializeObject<List<Repository>>(contactsJson);
contactsHelper.DeleteContact();
ObjContactList = list;
foreach (Repository obj in ObjContactList)
{
contactsHelper.CreateContacts(obj.name, obj.phone);
}
Device.BeginInvokeOnMainThread(() =>
{
labelModel.UpdateLabelValue.Execute(DateTime.Now.ToString());
});
}
}
else
{
Device.BeginInvokeOnMainThread(() =>
{
Toast.MakeText(context, "Error", ToastLength.Long).Show();
});
}
}
I'm calling this function on UI button
public partial class MainPage : ContentPage
{
ICallServiceHelper callServiceHelper = DependencyService.Get<ICallServiceHelper>();
public MainPage()
{
InitializeComponent();
}
private async void updateContactsBtn_Clicked(object sender, EventArgs e)
{
await callServiceHelper.UpdatePhonebook();
}
}
This is my ViewModel
public class LabelModel : BindableObject
{
string dateValue = "Date Value";
public LabelModel()
{
UpdateLabelValue = new Command<string>(UpdateLabel);
}
public ICommand UpdateLabelValue { get; }
public string DateDisplay
{
get => dateValue;
set
{
dateValue = value;
OnPropertyChanged(nameof(DateDisplay));
}
}
void UpdateLabel(string newLabel)
{
DateDisplay = newLabel;
}
}
And this is my Xaml file
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:HGB.ViewModel"
x:Class="HGB.MainPage">
<ContentPage.BindingContext>
<local:LabelModel/>
</ContentPage.BindingContext>
<StackLayout HorizontalOptions="Center" VerticalOptions="Center" Spacing="10">
<Button
Text="Update Phonebook"
x:Name="updateContactsBtn"
Clicked="updateContactsBtn_Clicked"
/>
<Label
VerticalOptions="Center"
HorizontalOptions="Center"
Text="{Binding DateDisplay}"
/>
</StackLayout>
I'm using the Helper method in my Foreground Service class, where it
gets called every 24 hours. What I'm trying to achieve is print the
exact time, when the phonebook was successfully updated and print that
date to my label.
For your problem, a simple method is to use MessagingCenter just as Jason mentioned.
You can send message in your CallServiceHelper and subscribe to this message in your ViewModel(LabelModel.cs).
Please refer to the following code:
1.In the constructor of your ViewMode(LabelModel.cs),subscribe to this message:
public LabelModel()
{
MessagingCenter.Subscribe<object, string>(this, "time", (sender, args) =>
{
System.Diagnostics.Debug.WriteLine("received time is: "+ args);
DateDisplay = args;
});
}
2.In your CallServiceHelper , public your message:
MessagingCenter.Send<object, string>(this, "time", "2022-4-8");

Xamarin Forms: Display error occurring in view model

I'm following tutorials/examples for a Xamarin Forms project, where there is a view with a C# code-behind, binding to a view model. However, I want to catch an exception occurring in the view model and display it in an alert or use any other common technique for displaying errors.
Here is the view, which reloads data using a refresh:
<?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="MyCompany.App.Views.DashboardPage"
xmlns:vm="clr-namespace:MyCompany.App.ViewModels"
xmlns:dashboard="clr-namespace:MyCompany.App.ViewModels.Dashboard;assembly=MyCompany.App"
Title="{Binding Title}">
...
<RefreshView x:DataType="dashboard:DashboardViewModel" Command="{Binding LoadItemsCommand}" IsRefreshing="{Binding IsBusy, Mode=TwoWay}">
... content
</RefreshView>
</ContentPage>
Then I have the C# code behind for the XAML:
public partial class DashboardPage : ContentPage
{
DashboardViewModel _viewModel;
public DashboardPage()
{
InitializeComponent();
BindingContext = _viewModel = new DashboardViewModel();
}
protected override void OnAppearing()
{
base.OnAppearing();
_viewModel.OnAppearing();
}
}
And finally the view model where the loading happens. It inherits from the BaseViewModel which is provided in the tutorials.
public class DashboardViewModel : BaseViewModel
{
private DashboardItemViewModel _selectedItem;
public ObservableCollection<DashboardItemViewModel> Items { get; }
public Command LoadItemsCommand { get; }
public Command<DashboardItemViewModel> ItemTapped { get; }
public DashboardViewModel()
{
Title = "Dashboard";
Items = new ObservableCollection<DashboardItemViewModel>();
LoadItemsCommand = new Command(async () => await ExecuteLoadItemsCommand());
ItemTapped = new Command<DashboardItemViewModel>(OnItemSelected);
}
async Task ExecuteLoadItemsCommand()
{
IsBusy = true;
try
{
Items.Clear();
var items = await GetItems();
foreach (var item in items)
{
Items.Add(item);
}
}
finally
{
IsBusy = false;
}
}
private static async Task<List<DashboardItemViewModel>> GetItems()
{
// Where errors happen
return items;
}
public void OnAppearing()
{
IsBusy = true;
SelectedItem = null;
}
public DashboardItemViewModel SelectedItem
{
get => _selectedItem;
set
{
SetProperty(ref _selectedItem, value);
OnItemSelected(value);
}
}
async void OnItemSelected(DashboardItemViewModel item)
{
if (item == null || item.Uri.IsNotSet())
return;
await Shell.Current.GoToAsync(item.Uri);
}
}
I can't see any overridable methods in ContentPage for catching exceptions. What's the best way to catch an exception and display it in an alert?
I'm not sure what exactly you want, but for catching errors I use try/catch method.
try
{
//your code here
}
catch(Exception exc)
{
await App.Current.MainPage.DisplayAlert("Warning", "Error: " + exc, "Ok");
}

MVVM Media Plugin not displaying picture

i need help with media plugin. I can see that the picture is taken however it doesnt display inthe content page. While debugging the app i can see the path but the picture is not there I have tried to follow this solution, Xamarin Forms MVVM (Prism) with Media.Plugin - How to get a taken picture from device storage
And this solution
Capturing and updating an image source using MVVM in Xamarin
however still nothing. My Binding works fine for everything. Just I dont know how to get the image
<Image
x:Name="Photo"
Grid.Row="2"
HeightRequest="100"
Source="{Binding postViewModel.ImageSource}"
VerticalOptions="Start" />
ViewModel
Ctor
public PostViewModel()
{
TakePictureCommand = new Command(async () => await TakePicture());
}
private async Task TakePicture()
{
await Permission();
var imageSource = await DependencyService.Get<IMessage>().ShowActionSheet(AppResources.AlertPhoto, AppResources.AlertNewPhoto, AppResources.AlertGallery);
if (imageSource == AppResources.AlertNewPhoto)
{
var imageFileName = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions()
{
Name = $"{DateTime.UtcNow}.jpg",
DefaultCamera = Plugin.Media.Abstractions.CameraDevice.Rear,
PhotoSize = PhotoSize.Medium,
SaveToAlbum = true
});
if (imageFileName == null)
{
DependencyService.Get<IMessage>().LongAlert(AppResources.AlertNoAcess);
}
else
{
ImageSource = ImageSource.FromStream(() => imageFileName.GetStream());
var test = ImageSource;
}
}
Master VM BInding
protected override void OnAppearing()
{
base.OnAppearing();
BindingContext = MasterPostsView= new MasterPostsViewModel();
}
class MasterPostsViewModel : BaseViewModel
{
public PostViewModel postViewModel { get; set; }
public CategoriesViewModel categoriesViewModel { get; set; }
public MasterPostsViewModel(INavigation navigation)
{
postViewModel = new PostViewModel();
categoriesViewModel = new CategoriesViewModel();
}
}
Have tried also
public string ImageSource { get => _imageSource; set { _imageSource = value; OnPropertyChanged(); } }
ImageSource = imageFileName.AlbumPath;
I have
protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

Windows store 8.1 dynamic binding not updating in UI

I have made a simple test for updating binded values in the UI but nothing seems to update, only intial values are set but never updated, what would i be missing?
code:
//the model class
public class DemoCustomer : INotifyPropertyChanged
{
// These fields hold the values for the public properties.
private Guid idValue = Guid.NewGuid();
private string customerNameValue = String.Empty;
private string phoneNumberValue = String.Empty;
public event PropertyChangedEventHandler PropertyChanged= delegate { };
// This method is called by the Set accessor of each property.
// The CallerMemberName attribute that is applied to the optional propertyName
// parameter causes the property name of the caller to be substituted as an argument.
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
// The constructor is private to enforce the factory pattern.
public DemoCustomer()
{
customerNameValue = "Customer";
phoneNumberValue = "(312)555-0100";
}
// This is the public factory method.
public static DemoCustomer CreateNewCustomer()
{
return new DemoCustomer();
}
// This property represents an ID, suitable
// for use as a primary key in a database.
public Guid ID
{
get
{
return this.idValue;
}
}
public string CustomerName
{
get
{
return this.customerNameValue;
}
set
{
if (value != this.customerNameValue)
{
this.customerNameValue = value;
NotifyPropertyChanged();
}
}
}
public string PhoneNumber
{
get
{
return this.phoneNumberValue;
}
set
{
if (value != this.phoneNumberValue)
{
this.phoneNumberValue = value;
NotifyPropertyChanged();
}
}
}
}
Then simply in my main page i do this:
public ObservableCollection<DemoCustomer> progcollection = new ObservableCollection<DemoCustomer>();
public MainPage()
{
this.InitializeComponent();
progcollection = new ObservableCollection<DemoCustomer>();
this.progcollection.Add(new DemoCustomer());
this.txtblk.DataContext = progcollection[0].CustomerName;
}
Then in a click listener for example i do this:
private void Button_Click_1(object sender, RoutedEventArgs e)
{
progcollection[0].CustomerName = "we changed the name!";
}
But nothing updates in the UI!!!
And here is my XAML:
<Page
x:Class="downloadprogressbinding.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:simpledownload"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock x:Name="txtblk" HorizontalAlignment="Left" Margin="994,421,0,0" TextWrapping="Wrap" Text="{Binding Mode=TwoWay}" VerticalAlignment="Top" Height="89" Width="226" FontSize="36"/>
<Button Content="Button" HorizontalAlignment="Left" Height="51" Margin="116,24,0,0" VerticalAlignment="Top" Width="407" Click="Button_Click_1"/>
</Grid>
Using path keyword in binding and specifying the field solved it,like this:
{Binding Path=thetext, Mode=TwoWay}

How to refresh data grid with new search results with MVVM Light

I'm using the latest MMVM Light windows 8 binaries and VS 2012 latest updates, so all is good there. I'm new to the MVVM Light framework, so it's an adjustment.
I have a Customers page with a grid that is searched with a textbox and button - the text box is bound and the button uses a command. The data is showing up in the view model just fine. I LINQ over the Customers List and set the Customers list property - all works well. The problem is, the page doesn't refresh. When I go to another page and return to the Customers page, the searched data is displayed.
I suspect the view model is static and needs to re-instantiated.
The follow are the respective code frags:
public partial class ViewModelLocator
{
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
if (ViewModelBase.IsInDesignModeStatic)
{
SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
}
else
{
SimpleIoc.Default.Register<IDataService, DataService>();
}
// Services
SimpleIoc.Default.Register<INavigationService, NavigationService>();
SimpleIoc.Default.Register<IMessenger, Messenger>();
// View Models
SimpleIoc.Default.Register<MainViewModel>();
SimpleIoc.Default.Register<CustomersViewModel>();
SimpleIoc.Default.Register<CustomerViewModel>(true);
SimpleIoc.Default.Register<ContactsViewModel>();
}
public MainViewModel Main
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModel>();
}
}
public CustomersViewModel Customers
{
get
{
return ServiceLocator.Current.GetInstance<CustomersViewModel>();
}
}
public CustomerViewModel Customer
{
get
{
return ServiceLocator.Current.GetInstance<CustomerViewModel>();
}
}
public ContactsViewModel Contacts
{
get
{
return ServiceLocator.Current.GetInstance<ContactsViewModel>();
}
}
public static void Cleanup()
{
}
}
}
public class CustomersViewModel : ViewModelBase
{
private readonly IDataService _dataService;
private INavigationService _navigationService;
private IMessenger _messenger;
public RelayCommand<string> RefreshClickCommand { get; set; }
public RelayCommand<string> SearchCustomersCommand { get; set; }
public const string CustomersPropertyName = "Customers";
private ObservableCollection<Customer> _customers = null;
public ObservableCollection<Customer> Customers
{
get
{
return _customers;
}
set
{
if (_customers == value)
{
return;
}
_customers = value;
RaisePropertyChanging(CustomersPropertyName);
}
}
public const string WelcomeTitlePropertyName = "WelcomeTitle";
private string _welcomeTitle = string.Empty;
public string WelcomeTitle
{
get
{
return _welcomeTitle;
}
set
{
if (_welcomeTitle == value)
{
return;
}
_welcomeTitle = value;
RaisePropertyChanged(WelcomeTitlePropertyName);
}
}
public const string CustomerSearchTermPropertyName = "CustomerSearchTerm";
private string _customerSearchTerm = string.Empty;
public string CustomerSearchTerm
{
get
{
return _customerSearchTerm;
}
set
{
if (_customerSearchTerm == value)
{
return;
}
_customerSearchTerm = value;
RaisePropertyChanging(CustomerSearchTermPropertyName);
}
}
public Customer SelectedItem
{
set
{
Customer customer = value;
_messenger.Send<Customer>(customer, "Customer");
_navigationService.Navigate(typeof(CustomerPage));
}
}
public CustomersViewModel(IDataService dataService)
{
_navigationService = SimpleIoc.Default.GetInstance<INavigationService>();
_messenger = SimpleIoc.Default.GetInstance<IMessenger>();
_dataService = dataService;
_dataService.GetData(
(item, error) =>
{
if (error != null)
{
// Report error here
return;
}
WelcomeTitle = item.Title + "Customers";
});
GetCustomers();
InitializeCommands();
}
private void InitializeCommands()
{
RefreshClickCommand = new RelayCommand<string>((item) =>
{
GetCustomers();
});
SearchCustomersCommand = new RelayCommand<string>((item) =>
{
SearchCustomers();
});
}
private void GetCustomers()
{
_customers = _dataService.GetCustomers();
}
private void SearchCustomers()
{
var cust = _dataService.GetCustomers();
List<Customer> customers = (from c in cust
where c.CompanyName.StartsWith(_customerSearchTerm)
orderby c.CompanyName
select c).ToList();
_customers = new ObservableCollection<Customer>(customers);
}
}
<common:LayoutAwarePage x:Class="SalesAccountManager.Views.RelationshipManager.CustomersPage"
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"
xmlns:common="using:SalesAccountManager.Common"
xmlns:ignore="http://www.ignore.com"
xmlns:telerikGrid="using:Telerik.UI.Xaml.Controls.Grid"
xmlns:WinRtBehaviors="using:WinRtBehaviors"
xmlns:Win8nl_Behavior="using:Win8nl.Behaviors"
mc:Ignorable="d ignore"
d:DesignHeight="768"
d:DesignWidth="1366"
DataContext="{Binding Customers, Source={StaticResource Locator}}">
....
<Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<TextBlock Text="Customers" FontFamily="Segoe UI" FontSize="38"/>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0, 0, 100, 0">
<TextBox Height="20" Width="600" Background="White" Text="{Binding CustomerSearchTerm, Mode=TwoWay}" />
<Button Background="White" Command="{Binding SearchCustomersCommand}">
<Image Source="../../Images/Search.jpg" Height="20" Width="20"></Image>
</Button>
</StackPanel>
</Grid>
Any guidance on this would be appreciated...
Thanks!

Resources