I'm trying to drag an image file from explorer into my wpf image control. My current code is
private void Image_Drop(object sender, DragEventArgs e)
{
string fpath = (string)e.Data.GetData(DataFormats.StringFormat);
BitmapImage tmpImage = new BitmapImage((new Uri(fpath)));
testImg.Source = tmpImage;
}
Which is currently giving me NullReferenceException error when I drop the file on the control.
Update:
Using Patrick's suggestion, by changing the code to this
private void Image_Drop(object sender, DragEventArgs e)
{
object data = e.Data.GetData(DataFormats.FileDrop);
foreach (string str in (string[])data)
{
BitmapImage tmpImage = new BitmapImage((new Uri(str)));
testImg.Source = tmpImage;
}
}
The image correctly update the source. Will probably need to add code for handling multiple images selection drop.
You should use the DataFormats.FileDrop. It will give a list of file names in the GetData. This is a working example from my own app:
object data = e.Data.GetData(DataFormats.FileDrop);
if (data is string[])
{
string[] files = (string[])data;
}
You are trying to get a file as a string, so I imagine it's your e.Data.GetData(DataFormats.StringFormat) line that is throwing. If you're dropping a bitmap onto your control then you can treat it as such. Try this.
private void Image_Drop(object sender, DragEventArgs e)
{
BitmapImage tmpImage = e.Data.GetData(DataFormats.Bitmap);
testImg.Source = tmpImage;
}
Although I recommend you put in code to ensure you are checking the type of what has been dragged onto your control before assuming it is a bitmap.
Related
I want to set image.Source via async stream in an UWP application. Otherwise the image will flicker when switch to other image source.
My code is as below. And the log shows it works. Certainly I put 2 image files in the corresponding path before I test the demo code.
But in fact I did not see any picture shown, why?
Log:
111111111111 image file path = C:\Users\tomxu\AppData\Local\Packages\a0ca0192-f41a-43ca-a3eb-f128a29b00c6_1qkk468v8nmy0\LocalState\2.jpg
22222222222
33333333333333
4444444444444
The thread 0x6d38 has exited with code 0 (0x0).
The thread 0x6a34 has exited with code 0 (0x0).
111111111111 image file path = C:\Users\tomxu\AppData\Local\Packages\a0ca0192-f41a-43ca-a3eb-f128a29b00c6_1qkk468v8nmy0\LocalState\1.jpg
22222222222
33333333333333
4444444444444
Code:
private async void setImageSource(string imageFilePath)
{
StorageFile sFile = await StorageFile.GetFileFromPathAsync(imageFilePath);
Debug.WriteLine("111111111111 image file path = " + imageFilePath);
Stream fileStream = await sFile.OpenStreamForReadAsync();
Debug.WriteLine("22222222222");
InMemoryRandomAccessStream ras = new InMemoryRandomAccessStream();
Debug.WriteLine("33333333333333");
await fileStream.CopyToAsync(ras.AsStreamForRead());
Debug.WriteLine("4444444444444");
BitmapImage bi = new BitmapImage();
bi.SetSource(ras);
image1.Source = bi;
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
string fullFolder = ApplicationData.Current.LocalFolder.Path;
if (count % 2 == 1)
{
setImageSource(fullFolder + #"\1.jpg");
//image1.Source = new BitmapImage(new Uri(#"ms-appx:///Assets/1.jpg"));
}
else
{
setImageSource(fullFolder + #"\2.jpg");
//image1.Source = new BitmapImage(new Uri(#"ms-appx:///Assets/2.jpg"));
}
count++;
}
Here is an example of how I convert a base64 image string to a BitmapImage..
var ims = new InMemoryRandomAccessStream();
var bytes = Convert.FromBase64String(base64String);
var dataWriter = new DataWriter(ims);
dataWriter.WriteBytes(bytes);
await dataWriter.StoreAsync();
ims.Seek(0);
var img = new BitmapImage();
img.SetSource(ims);
ims.Dispose();
return img;
Try some of the things I'm doing there. Like I notice your code is not setting the seek of the InMemoryReadAccessStream
For your question, I have something to clarify with you.
Your pictures are always in the application data folder. If you want to show it at runtime by programming, the easy way is using the ms-appdata URI scheme to refer to files that come from the app's local, roaming, and temporary data folders. Then, you could use this URL to initialize the BitmapImage object. With this way, you don't need to manually manipulate the file stream.
private void setImageSource(int i)
{
BitmapImage bi = new BitmapImage(new Uri("ms-appdata:///local/"+i+".png"));
image1.Source = bi;
}
private int count = 0;
private void Button_Click(object sender, RoutedEventArgs e)
{
if (count % 2 == 1)
{
setImageSource(1);
}
else
{
setImageSource(2);
}
count++;
}
If you say you have to manipulate the file stream to initialize the BitmaImage, then please add some break points to debug your code. If you add break points to check the InMemoryRandomAccessStream after call CopyToAsync method, you will see that its size is 0. It meant that the file stream has not been wrote to it. To solve this issue, you need to set a buffer size for it. Note: you used ras.AsStreamForRead() method, it's incorrect. You're writing stream to it, so you need to call ras.AsStreamForWrite().
The code looks like the following:
private async void setImageSource(string imageFilePath)
{
StorageFile sFile = await StorageFile.GetFileFromPathAsync(imageFilePath);
using (Stream fileStream = await sFile.OpenStreamForReadAsync())
{
using (InMemoryRandomAccessStream ras = new InMemoryRandomAccessStream())
{
await fileStream.CopyToAsync(ras.AsStreamForWrite((int)fileStream.Length));
ras.Seek(0);
BitmapImage bi = new BitmapImage();
bi.SetSource(ras);
img.Source = bi;
}
}
}
private int count = 0;
private void Button_Click(object sender, RoutedEventArgs e)
{
string fullFolder = ApplicationData.Current.LocalFolder.Path;
if (count % 2 == 1)
{
setImageSource(fullFolder + #"\1.jpg");
}
else
{
setImageSource(fullFolder + #"\2.jpg");
}
count++;
}
In addition, like #visc said, you need to call ras.Seek(0) method to reset the stream to beginning, else the image will not show there.
I'm having an issue with duplicated content from redirected output.
In my forms I have two buttons: Run and Clear.
public partial class BatchRun : Form
{
Process process = new Process();
public BatchRun()
{
InitializeComponent();
}
private void RunBTN_Click(object sender, EventArgs e)
{
//initiate the process
this.process.StartInfo.FileName = sMasterBATname;
this.process.StartInfo.UseShellExecute = false;
this.process.StartInfo.CreateNoWindow = true;
this.process.StartInfo.RedirectStandardOutput = true;
this.process.OutputDataReceived += new DataReceivedEventHandler(StandardOutputHandler);
this.process.StartInfo.RedirectStandardInput = true;
this.process.Start();
this.process.BeginOutputReadLine();
}
public void StandardOutputHandler(object sender, DataReceivedEventArgs outLine)
{
BeginInvoke(new MethodInvoker(() =>
{
Label TestLBL = new Label();
TestLBL.Text = text.TrimStart();
TestLBL.AutoSize = true;
TestLBL.Location = new Point(10, CMDpanel.AutoScrollPosition.Y + CMDpanel.Controls.Count * 20);
CMDpanel.Controls.Add(TestLBL);
CMDpanel.AutoScrollPosition = new Point(10, CMDpanel.Controls.Count * 20);
}));
}
private void ClearBTN_Click(object sender, EventArgs e)
{
CMDpanel.Controls.Clear();
this.process.CancelOutputRead();
this.process.Close();
this.process.Refresh();
}
}
This works great if I want to run process only once i.e. close the forms once process has completed.
However, I need to allow user to rerun the same process or run a new one hence I have added a clear button the clear various controls etc.
The problem I'm having is that after clicking clear button, I want to click run button again without closing which should then run the sMAsterBAT file(CMD).
StandardOutputHandler seems to be including content of the previous run as well as the new one resulting in duplicated labels in my CMDpanel.
Is this stored in some kind of buffer? If so, How do i clear it to allow me a rerun?
Could someone explain why this is happening and how to resolve it please.
Spoke to someone at work who fixed it for me. So easy lol
private void ClearBTN_Click(object sender, EventArgs e)
{
CMDpanel.Controls.Clear();
this.process.CancelOutputRead();
this.process.Close();
this.process.Refresh();
this.process = new Process(); // this line resolved my issue!!
}
}
found this function online, which works great... except I can't figure out how to default it to print in landscape.
private void PrintClick(object sender, RoutedEventArgs e)
{
PrintDialog dialog = new PrintDialog();
if (dialog.ShowDialog() == true)
{ dialog.PrintVisual(_PrintCanvas, "My Canvas"); }
}
How does one actually set the default to print my wpf content to landscape mode?
Edit: Fixed variable name, mentioned by #SHIN JaeGuk
private void PrintClick(object sender, RoutedEventArgs e)
{
PrintDialog dialog = new PrintDialog();
if (dialog.ShowDialog() == true)
{
//Set PageOrientation to Landscape
dialog.PrintTicket.PageOrientation = PageOrientation.Landscape;
dialog.PrintVisual(_PrintCanvas, "My Canvas");
}
}
Original Answer
This has already been answered:
Setting PageOrientation for the Wpf DocumentViewer PrintDialog
End Original Answer
Edit:
It appears there is a problem with the PrintTicket and printing visuals, check out:
Same question on MSDN
The original poster on the MSDN forum posted on the last post that the work around they used was to basically capture the visual and convert to xps document for printing, this will allow the usage of PrintTicket to set the orientation of the printed document.
private void PrintClick(object sender, RoutedEventArgs e)
{
PrintDialog dialog = new PrintDialog();
if (dialog.ShowDialog() == true)
{
dialog.PrintTicket.PageOrientation=System.Printing.PageOrientation.Landscape;
dialog.PrintVisual(this, "First LandScape");
}
}
You need to add a reference to ReachFramework.dll and System.Printing.dll each.
I am working on a Windows 8 metro app and having multiple SettingsFlyout items which get added by below mentioned code
SettingsCommand cmd1 = new SettingsCommand("sample", "Color Settings", (x) =>
{
// create a new instance of the flyout
SettingsFlyout settings = new SettingsFlyout();
// set the desired width. If you leave this out, you will get Narrow (346px)
// optionally change header and content background colors away from defaults (recommended)
// if using Callisto's AppManifestHelper you can grab the element from some member var you held it in
// settings.HeaderBrush = new SolidColorBrush(App.VisualElements.BackgroundColor);
settings.HeaderBrush = new SolidColorBrush(Colors.Black);
settings.HeaderText = string.Format("Color Settings", App.VisualElements.DisplayName);
settings.Background = new SolidColorBrush(_background);
settings.Margin = new Thickness(0);
// provide some logo (preferrably the smallogo the app uses)
BitmapImage bmp = new BitmapImage(App.VisualElements.SmallLogoUri);
settings.SmallLogoImageSource = bmp;
// set the content for the flyout
settings.Content = new ColorSettings();
settings.HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Stretch;
// open it
settings.IsOpen = true;
// this is only for the test app and not needed
// you would not use this code in your real app
// ObjectTracker.Track(settings);
});
Currently using (SettingsPane.Show()) i can be able to show the added flyout items list but I want to programmatically open any setting Flyout item instead of opening a flyout list.
Create a new class
public class SettingsFlyout
{
private const int _width = 346;
private Popup _popup;
/// <summary>
/// Show the Flyout with the UserControl as content
/// </summary>
/// <param name="control"></param>
public void ShowFlyout(UserControl control)
{
_popup = new Popup();
_popup.Closed += OnPopupClosed;
Window.Current.Activated += OnWindowActivated;
_popup.IsLightDismissEnabled = true;
_popup.Width = _width;
_popup.Height = Window.Current.Bounds.Height;
control.Width = _width;
control.Height = Window.Current.Bounds.Height;
_popup.Child = control;
_popup.SetValue(Canvas.LeftProperty, Window.Current.Bounds.Width - _width);
_popup.SetValue(Canvas.TopProperty, 0);
_popup.IsOpen = true;
}
private void OnWindowActivated(object sender, Windows.UI.Core.WindowActivatedEventArgs e)
{
if (e.WindowActivationState == Windows.UI.Core.CoreWindowActivationState.Deactivated)
{
_popup.IsOpen = false;
}
}
void OnPopupClosed(object sender, object e)
{
Window.Current.Activated -= OnWindowActivated;
}
}
In a XAML page take a button and then write the button click event.
private void Button_Click_1(object sender, RoutedEventArgs e)
{
SettingsFlyout flyout = new SettingsFlyout();
flyout.ShowFlyout(new FlyoutContentUserControl());
}
Please note one thing FlyoutContentUserControl is the user control which you would like to show.
Credits goes to Q42.WinRT
The code you posted registers a SettingsCommands to the system settings pane. When your command is invoked from the system settings pane, you new up a SettingsFlyout instance and set IsOpen=True on it.
You just need to refactor this code to a separate method (e.g. ShowColorSettingsFlyout()), and also call that method from your Button.Click event handler. You can create a new Callisto SettingsFlyout and set IsOpen=True on it anywhere.
In App.xaml.cs add the following to register your SettingsFlyout e.g. CustomSetting ...
protected override void OnWindowCreated(WindowCreatedEventArgs args)
{
SettingsPane.GetForCurrentView().CommandsRequested += OnCommandsRequested;
}
private void OnCommandsRequested(SettingsPane sender, SettingsPaneCommandsRequestedEventArgs args)
{
args.Request.ApplicationCommands.Add(new SettingsCommand(
"Custom Setting", "Custom Setting", (handler) => ShowCustomSettingFlyout()));
}
public void ShowCustomSettingFlyout()
{
CustomSetting CustomSettingFlyout = new CustomSetting();
CustomSettingFlyout.Show();
}
Then anywhere in your code you want to programmatically open the CustomSetting flyout, call ShowCustomSettingFlyout, e.g. in the event handler for a button click...
void Button_Click_1(object sender, RoutedEventArgs e)
{
ShowCustomSettingFlyout()
}
Adapted from: Quickstart: Add app settings (XAML).
I want to Save image to Database.The image is selected by Browsing and is loaded to Imagebox in silverlight application in C#.Net.
I want to assign this loaded image to Object that is used to Saving the data.
Below is my Code.
private void btnBrowse_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog objFileDialog = new OpenFileDialog();
bool? IsSelected = objFileDialog.ShowDialog();
objFileDialog.Filter = "Pictures (*.jpg)|*.jpg";
objFileDialog.FilterIndex = 1;
if (IsSelected == true)
{
BitmapImage bitImage = new BitmapImage();
bitImage.SetSource(objFileDialog.File.OpenRead());
image1.Source = bitImage;
//Image1 is object of Image
}
}
Code of Object that is carrying Data to Save Method in Service File.
private void btnSave_Click(object sender, RoutedEventArgs e)
{
var objData = new ServiceReference1.Data_Registration();
objData .AY_ID = newAcadYearId;
objData .CellNo = txtCellNo.Text;
objData .ImageId = ;
services.DataRegAsync(objAlumni);
}
Please Suggest how can i assign Selected Image to my Object objdata.