I have problem with getting of FolderBrowserDialog in white. I think that it should be assigned as a modal window but it isn't.
FolderBrowserDialog in DialogService.cs:
public FolderBrowserResult ShowFolderbrowserDialog(string storageFolder)
{
var dialog = new FolderBrowserDialog
{
Description = storageFolder
};
var result = new FolderBrowserResult
{
Result = dialog.ShowDialog() != DialogResult.OK,
Path = dialog.SelectedPath
};
return result;
}
Method called after click on browse button:
private void OnBrowseForTargetFolder(object sender, RoutedEventArgs e)
{
var result = dialogService.ShowFolderbrowserDialog(Properties.Resources.StorageFolder);
if (result.Result) return;
Project.PathToStorage = result.Path;
completePath = string.Format("{0}\\{1}", result.Path, Guid.NewGuid());
Directory.CreateDirectory(completePath);
}
Test:
public class LoggerTests
{
private Application application;
private MainWindowPage mainWindowPage;
[TestInitialize]
public void TestInitialize()
{
application = Application.Launch(#"PML.exe");
StartBlankApplication();
}
[TestMethod]
public void StartExistingProject()
{
mainWindowPage.StartExistingProjectButton.Click();
var modalWindows = new List<Window>();
Retry.For(() =>
{
modalWindows = mainWindowPage.applicationWindow.ModalWindows();
}, TimeSpan.FromSeconds(5));
var mod = modalWindows;
}
private MainWindowPage StartBlankApplication()
{
var appWindow = application.GetWindow("PML");
mainWindowPage = new MainWindowPage(appWindow);
return mainWindowPage;
}
private NewProjectConfigurationPage ConfigureBlankProject()
{
Window secondAppWindow = null;
Retry.For(() =>
{
secondAppWindow = application.GetWindow("PML");
}, TimeSpan.FromSeconds(5));
var newProjectConfiguration = new NewProjectConfigurationPage(secondAppWindow);
newProjectConfiguration.VesselName.Text = "Test";
newProjectConfiguration.BrowseButton.Click();
return newProjectConfiguration;
}
}
In StartExistingProject method is problem that variable mod is empty. And no FolderBrowserDialog is opened. But when I run app normally everything runs OK.
Solved - There must be setted owner to modal dialog. So
var wrapper = new WindowWrapper(this);
dialog.ShowDialog(wrapper)
solved my problem.
Related
i am creating mobile application where user can post adverts with pictures and text. I am using Media.Plugin by James Montemagno. That works very well. Also the user should be able to tap on the picture to review and possibly delete. I am not sure how to access these pictures, i dont know where they are stored so even if i would want to delete them i am not sure how to access each picture. COuld you please help me?
The user is able to take several images and then they are displayed on the main page. I would like the user to be able to review them once again and then if he continues with them to the second page he will upload some other data and on the third page it should all display together. How can i Display pictures on the third page?
public partial class AddingPage : ContentPage
{
AdLogEntry adLogEntry = new AdLogEntry();
//CameraService cameraService = new CameraService();
public byte[] imageAsBytes;
public string pathLabel;
private const int MaxColumns = 3;
private int _currentRow = 0;
private int _currentColumn = 0;
public AddingPage()
{
InitializeComponent();
}
protected override async void OnAppearing()
{
base.OnAppearing();
await MainProgressBar.ProgressTo(0, 250, Easing.Linear); ;
}
private async void NextStep_Clicked(object sender, EventArgs e)
{
await Navigation.PushAsync(new Informations());
}
private async void TakePicture_Clicked(object sender, EventArgs e)
{
await TakePicture();
}
private async Task TakePicture()
{
MediaFile file = null;
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
await DisplayAlert("Nemáme přístup", "Nelze nalézt kameru", "OK");
return;
}
var imageSource = await DisplayActionSheet("Foto", "Cancel", null, new string[] { "Pořídit novou fotku", "Nahrát foto z galerie" });
var photoName = Guid.NewGuid().ToString() + ".jpg";
switch (imageSource)
{
case "Pořídit novou fotku":
file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
SaveToAlbum = true,
Directory = "Photos",
Name = photoName
});
//Get the public album path
var aPpath = file.AlbumPath;
//Get private path
var path = file.Path;
break;
case "Nahrát foto z galerie":
file = await CrossMedia.Current.PickPhotoAsync();
//Directory.GetFiles( "Photos");
break;
default:
break;
}
if (file == null)
return;
// Photo => Grid
_currentColumn++;
if (_currentColumn > MaxColumns - 0)
{
_currentColumn++;
_currentRow++;
// Add a new row definition by copying the first row.
ImageGridContainer.RowDefinitions.Add(ImageGridContainer.RowDefinitions[0]);
}
var newImage = new Image()
{
Source = ImageSource.FromFile(file.Path),
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
Aspect = Aspect.AspectFill,
Scale = 0
};
ImageGridContainer.Children.Add(newImage, _currentColumn, _currentRow);
await Task.Delay(250);
await newImage.ScaleTo(1, 250, Easing.SpringOut);
}
I am having an issue with my code to add button from json where the first attempt i click add button, the menuflyout won't have any respond but second click attempt then it will work properly.
Can advise did i do anything wrong? Thanks.
private async void AddButton_Click(object sender, RoutedEventArgs e)
{
List<ClientList> clientLists;
var jsonSerializer = new DataContractJsonSerializer(typeof(List<ClientList>));
var myStream = await ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(CLIENTSLIST);
clientLists = (List<ClientList>)jsonSerializer.ReadObject(myStream);
var menuFlyout = new MenuFlyout();
int isEmpty = myGrid.Children.Count;
if (isEmpty == 0)
{
foreach (var device in clientLists)
{
var menuFlyoutItem = new MenuFlyoutItem() { Name = device.clientname, Text = device.clientname };
menuFlyoutItem.Tag = device.clientaddress;
menuFlyoutItem.Click += AddMenuFlyoutItem_Click;
menuFlyout.Items.Add(menuFlyoutItem);
}
}else
{
foreach (var device in clientLists)
{
bool toAddButton = true;
foreach (Button btn in myGrid.Children.OfType<Button>())
{
if (btn.Content.ToString() == device.clientname)
{
toAddButton = false;
}
}
if (toAddButton)
{
var menuFlyoutItem = new MenuFlyoutItem() { Name = device.clientname, Text = device.clientname };
menuFlyoutItem.Tag = device.clientaddress;
menuFlyoutItem.Click += AddMenuFlyoutItem_Click;
menuFlyout.Items.Add(menuFlyoutItem);
}
}
}
AddButton.Flyout = menuFlyout;
}
The problem is you are loading the data asynchronously here:
var myStream = await ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(CLIENTSLIST);
When this happens, UI continues executing the Click event, so the button is clicked (and Flyout is null the first time) and Flyout will never display. You should rather load the Flyout before that - either when the page loads or when the data source changes, so that when the user clicks, the flyout is already there. Doing loading in Click is simply too late, if you need an asynchronous operation to finish.
Alternatively you could set the flyout right at the start:
private async void AddButton_Click(object sender, RoutedEventArgs e)
{
var menuFlyout = new MenuFlyout();
AddButton.Flyout = menuFlyout;
List<ClientList> clientLists;
var jsonSerializer = new DataContractJsonSerializer(typeof(List<ClientList>));
var myStream = await ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(CLIENTSLIST);
clientLists = (List<ClientList>)jsonSerializer.ReadObject(myStream);
int isEmpty = myGrid.Children.Count;
if (isEmpty == 0)
{
foreach (var device in clientLists)
{
var menuFlyoutItem = new MenuFlyoutItem() { Name = device.clientname, Text = device.clientname };
menuFlyoutItem.Tag = device.clientaddress;
menuFlyoutItem.Click += AddMenuFlyoutItem_Click;
menuFlyout.Items.Add(menuFlyoutItem);
}
}else
{
foreach (var device in clientLists)
{
bool toAddButton = true;
foreach (Button btn in myGrid.Children.OfType<Button>())
{
if (btn.Content.ToString() == device.clientname)
{
toAddButton = false;
}
}
if (toAddButton)
{
var menuFlyoutItem = new MenuFlyoutItem() { Name = device.clientname, Text = device.clientname };
menuFlyoutItem.Tag = device.clientaddress;
menuFlyoutItem.Click += AddMenuFlyoutItem_Click;
menuFlyout.Items.Add(menuFlyoutItem);
}
}
}
}
This way, the flyout will appear, but will be empty until the asynchronous loading finishes and the items are actually added. Here you are just reading a file, so it should be barely noticeable. Although not as clean as pre-loading the flyout, it should get the job done too.
Can anybody help me with this code in my Xamarin project. I am trying to set a loading wheel (to signify that an action is happening and to let the user know to wait) when the "Login" button is clicked. For some reason since the function is asynchronous the loading wheel is never set to visible when the API code is run. It just fails to show up when I click login, however, it still does the login function.
// Defined up above in the file
var loginButton = new Button
{
Text = "Login",
};
loginButton.BackgroundColor = Color.Navy;
loginButton.TextColor = Color.White;
loginButton.Clicked += OnLoginButtonClicked;
async void OnLoginButtonClicked(object sender, EventArgs e)
{
loadingWheel.IsVisible = true;
try
{
var restUrl = "*******";
var content = string.Empty;
using (var client = new HttpClient())
{
string body = "{\"UserName\":\"" + usernameEntry.Text + "\", \"Password\":\"" + passwordEntry.Text + "\"}";
var contentType = new StringContent(body, Encoding.UTF8, "application/json");
var result = client.PostAsync(restUrl, contentType).Result;
content = await result.Content.ReadAsStringAsync();
}
if (content.ToLower() != "false")
{
var menuPage = new MenuPage();
NavigationPage = new NavigationPage(new HomePage());
RootPage = new Views.MainPage();
RootPage.Master = menuPage;
RootPage.Detail = NavigationPage;
MainPage = RootPage;
}
else
{
messageLabel.Text = "Username or password incorrect. Please try again.";
passwordEntry.Text = string.Empty;
}
}
catch (Exception ex)
{
messageLabel.Text = "Please check the internet connection for the connectivity.";
}
}
If I comment out the entire try block then the loading wheel does show up. It just does not work with the code in there.
Can anybody help me solve this problem? Thanks.
I think you can try with BeginInvokeOnMainThread
Device.BeginInvokeOnMainThread (() => {
loadingWheel.IsVisible = true;
});
UPDATE
I have also create this REPO... it works without BeginInvodeOnMainThread
public class MyPage6 : ContentPage
{
ActivityIndicator _ac = new ActivityIndicator { IsVisible = false, IsRunning = false };
public MyPage6()
{
Button b = new Button {Text = "Press for ActivityIndicator" };
b.Clicked += B_Clicked;
Content = new StackLayout
{
Children = {
_ac,
b,
new Label { Text = "Hello ContentPage" }
}
};
}
async void B_Clicked(object sender, EventArgs e)
{
_ac.IsRunning = true;
_ac.IsVisible = true;
await Task.Delay(2000);
_ac.IsRunning = false;
_ac.IsVisible = false;
}
}
I am trying to write a code in which I got as xml format for the first image api from wikipedia. Now I want to parse it through c#. But I cannot get the image while running code. here is my code.
namespace WikiAPIWinForm
{
public partial class WikiForm : Form
{
private const string url1_Image1 = "https://en.wikipedia.org/w/api.php?action=query&titles=File:Schloss%20Neuschwanstein%202013.jpg&prop=imageinfo&iiprop=comment|url|dimensions&format=xml&iiurlwidth=300"; //show 1st image
private const string url1_Image2 = "https://en.wikipedia.org/w/api.php?action=query&titles=File:Neuschwanstein%20castle.jpg&prop=imageinfo&iiprop=comment|url|dimensions&format=xml&iiurlwidth=300";// show another image
private const string url1_Image3 = "https://en.wikipedia.org/w/api.php?action=query&titles=File:Hohenschwangau_-_Schloss_Neuschwanstein5.jpg&prop=imageinfo&iiprop=comment|url|dimensions&format=xml&iiurlwidth=300";// show another image
public WikiForm()
{
InitializeComponent();
}
XDocument xmlDocument1 = XDocument.Load(url1_Image1);
XDocument xmlDocument2 = XDocument.Load(url1_Image2);
XDocument xmlDocument3 = XDocument.Load(url1_Image3);
var image1 = (from page in xmlDocument1.Descendants("page")
select new AllImage
{
Title1 = page.Attribute("title").Value,
Imagerepository1 = page.Attribute("imagerepository").Value,
Url1 = page.Element("imageinfo").Element("ii").Attribute("thumburl").Value
});
ShowImages1(image1);
var image2 = (from page in xmlDocument2.Descendants("page")
select new AllImage
{
Title2 = page.Attribute("title").Value,
Imagerepository2 = page.Attribute("imagerepository").Value,
Url2 = page.Element("imageinfo").Element("ii").Attribute("thumburl").Value
});
ShowImages2(image2);
var image3 = (from page in xmlDocument3.Descendants("page")
select new AllImage
{
Title3 = page.Attribute("title").Value,
Imagerepository2 = page.Attribute("imagerepository").Value,
Url3 = page.Element("imageinfo").Element("ii").Attribute("thumburl").Value
});
ShowImages3(image3);
}
private void ShowImages1(IEnumerable<AllImage> image1)
{
var image = image1.First();
pictureLabel1.Text = image.Title1;
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox1.LoadAsync(image.Url1);// asynchronous loading
}
private void ShowImages2(IEnumerable<AllImage> image2)
{
var image = image2.First();
pictureLabel2.Text = image.Title2;
pictureBox2.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox2.LoadAsync(image.Url2);// asynchronous loading
}
private void ShowImages3(IEnumerable<AllImage> image3)
{
var image = image3.First();
pictureLabel3.Text = image.Title3;
pictureBox3.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox3.LoadAsync(image.Url3);// asynchronous loading
}
}
You need something like
private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false; // to prevent a new download until you have finished the old one
XDocument xmlDocument = XDocument.Load(url1_Image);
var images = (from page in xmlDocument.Descendants("page")
select new AllImage
{
Title = page.Attribute("title").Value,
Imagerepository = page.Attribute("imagerepository").Value,
Url = page.Element("imageinfo").Element("ii").Attribute("url").Value
});
ShowImages(images);
};
private void ShowImages(IEnumerable<AllImage> images)
{
var image = images.First();
label1.Text = image.Title;
pictureBox1.LoadAsync(image.Url); // asynchronous loading
}
After downloading the image you need to make the button available.
void pictureBox1_LoadCompleted(object sender, AsyncCompletedEventArgs e)
{
button1.Enabled = true;
}
We strongly recommend to give normal names to the controls. For example, buttonLoad, labelTitle, pictureBoxWikiImage.
In addition, I see in XML information about only one image. So, for what the IEnumerable collection?
Hello i have a next code:
When thumbnail is tapped i have to download file if it doesn't exist localy, or open if exists.
The problem is that if i make very quick two taps - it downloads same file two times - how to prevent this?
As you can see i tried using bool - didn't help.
Tried also using private static SemaphoreSlim TapSemaphore = new SemaphoreSlim(1, 1); - didn't help
public bool IsCurrentlyDownloading = false;
private async void assetThumbnail_Tapped(object sender, TappedRoutedEventArgs e)
{
await OpenOrDownload();
}
private async Task OpenOrDownload()
{
if (FileIsDownloaded == true)
{
string filename = Util.GetLocalFileName(CustomerAsset.file.id, "CustomerAssetFile");
var options = new Windows.System.LauncherOptions();
options.DisplayApplicationPicker = false;
var sampleFile = await ApplicationData.Current.LocalFolder.GetFileAsync(filename);
await Windows.System.Launcher.LaunchFileAsync(sampleFile, options);
}
else
{
if (!IsCurrentlyDownloading)
{
IsCurrentlyDownloading = true;
DownloadFiles();
}
}
}
Why don't you use a flag (bool, sync object, something) to mark that the downloading or displaying operation is in progress and in this case do not show it.
Rather conceptually, something like this:
public bool IsCurrentlyDownloading = false;
bool isWorking = false;
private async void assetThumbnail_Tapped(object sender, TappedRoutedEventArgs e)
{
if(!isWorking)
await OpenOrDownload();
}
private async Task OpenOrDownload()
{
isWorking = true;
if (FileIsDownloaded == true)
{
string filename = Util.GetLocalFileName(CustomerAsset.file.id, "CustomerAssetFile");
var options = new Windows.System.LauncherOptions();
options.DisplayApplicationPicker = false;
var sampleFile = await ApplicationData.Current.LocalFolder.GetFileAsync(filename);
await Windows.System.Launcher.LaunchFileAsync(sampleFile, options);
}
else
{
if (!IsCurrentlyDownloading)
{
IsCurrentlyDownloading = true;
DownloadFiles();
}
}
isWorking = false;
}