How to send information from one window to another? WPF - c#

How do I send information from one wpf window to another window. What I wanted is for string filepath to save the information it gets the first time it is called.
This is the problem, when I click button1 from window1.xmal.cs it calls openfile() from DocumentManager.cs. And when I access filepath from window2.xmal.cs it gives an empty string. I want to save the filepath string I got from when it was called from window1.xmal.cs.
Here is what I have:
window1.xmal.cs
DocumentManager mgr = new DocumentManager();
private void Button1_Click(object sender, RoutedEventArgs e) {
ImageSource imgsource = new BitmapImage(new Uri(mgr.openfile().ToString()));
themeImage.Source = imgsource;
}
DocumentManager.cs
public string filePath;
public object openfile() {
OpenFileDialog open = new OpenFileDialog();
bool? result = open.ShowDialog();
if (result == true) {
filePath = open.FileName;
}
return filePath;
}

I think your problem is the way you are instantiating the DocumentManager class.
I've made an example that works. Here's the code:
MainWindow
public partial class MainWindow : Window
{ DocumentManager mgr;
Window2 w2;
public MainWindow() { InitializeComponent(); }
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{ mgr = new DocumentManager(); w2 = new Window2(); w2.Show(); }
private void Button_Click(object sender, RoutedEventArgs e)
{ ImageSource imgsource; string imglocation;
try {
imglocation = mgr.openfile().ToString();
imgsource = new BitmapImage(new Uri(imglocation));
result.Text = imglocation;
w2.imgsource = imgsource;
}
catch (Exception ex)
{ System.Windows.MessageBox.Show(ex.Message); }
}
}
DocumentManager
class DocumentManager
{
public string filePath;
public string openfile()
{
Microsoft.Win32.OpenFileDialog open = new Microsoft.Win32.OpenFileDialog();
bool? result = open.ShowDialog();
if (result == true) { filePath = open.FileName; }
else { filePath = "Nothing Opened"; }
return filePath;
}
}
MainWindow XAML
<Window x:Class="CrossClassDialog.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="120" Width="350" Loaded="MainWindow_Loaded">
<Grid>
<Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Click="Button_Click"/>
<TextBlock x:Name="result" HorizontalAlignment="Left" Text="TextBlock" VerticalAlignment="Top" Margin="0,30,0,0"/>
</Grid>
</Window>
Window2 XAML
<Window x:Class="CrossClassDialog.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window2" Height="300" Width="300">
<Grid>
<Viewbox HorizontalAlignment="Left" VerticalAlignment="Top">
<Image x:Name="OpenedImage" Source="{Binding ImageSource}" />
</Viewbox>
</Grid>
</Window>
Add this property in Window2
private ImageSource _imgsource;
public ImageSource imgsource
{
get { return _imgsource; }
set
{
_imgsource = value;
OpenedImage.Source = value;
}
}
By the way, I changed a few things like the type your openfile() method returns.

Related

Access InkToolbar placed in parent element from programmatically generated child elements

I have a UserControl which contains a InkToolbar. In this control I'm generating another set of UserControls based on user input. In each of those programmatically generated controls, contains a InkCanvas.
This is the parent UserControl & the code behind.
Main.xaml
<UserControl
x:Class="uwp.Main"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:uwp_mvvm"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0">
<InkToolbar x:Name="InkToolbar" Background="Black" Margin="10 0 0 0" VerticalAlignment="Center"/>
</StackPanel>
<ScrollViewer ZoomMode="Enabled" Background="DarkGray" x:Name="ScrollViewer" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" MinZoomFactor="0.25" Width="Auto" Height="Auto" MaxZoomFactor="4" Grid.Row="1">
<StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
<ItemsControl x:Name="PagesItemsControl" ItemsSource="{x:Bind Pages, Mode=OneWay}" HorizontalAlignment="Center" VerticalAlignment="Top">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:TestControl x:Name="TestControl" Page="{Binding}" Margin="4 4" InkToolbarControl="{Binding Path=InkToolbar, ElementName=InkToolbar}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ScrollViewer>
</Grid>
</UserControl>
Main.xaml.cs
public sealed partial class MainViewer : UserControl
{
public MainViewer()
{
this.InitializeComponent();
}
private void EventTriggerChanged(object sender, PropertyChangedEventArgs e)
{
var trigger = sender as EventTriggerTestControl;
if (trigger != null)
RaiseChanged(e.PropertyName);
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaiseChanged(string propName)
{
if (PropertyChanged != null)
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propName));
}
private PdfDocument pdfDocument = null;
private string password = string.Empty;
private ObservableCollection<PdfPage> pages = new ObservableCollection<PdfPage>();
public string Password
{
private get { return password; }
set { if (value != password) { password = value; } }
}
public ObservableCollection<PdfPage> Pages
{
get { return pages; }
set { if (value != pages) { pages = value; } }
}
public StorageFile File
{
get { return (StorageFile)GetValue(FileProperty); }
set { SetValue(FileProperty, value); }
}
public static readonly DependencyProperty FileProperty =
DependencyProperty.Register(nameof(File), typeof(StorageFile), typeof(MainViewer), new PropertyMetadata(null, new PropertyChangedCallback(OnDocumentChanged)));
private static void OnDocumentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (object.Equals(e.NewValue, e.OldValue) || e.NewValue is null)
return;
d.RegisterPropertyChangedCallback(FileProperty, CaptureDocument);
}
private async static void CaptureDocument(DependencyObject sender, DependencyProperty dp) => await (sender as MainViewer).OpenFileAsync(sender.GetValue(dp) as StorageFile);
private async Task OpenFileAsync(StorageFile file)
{
try
{
if (file == null)
throw new ArgumentNullException(nameof(file));
var files = await ApplicationData.Current.LocalFolder.GetFilesAsync(CommonFileQuery.OrderByName);
if (files.Where(x => x.Name == file.Name).ToList().Count == 0)
await file.CopyAsync(ApplicationData.Current.LocalFolder, file.Name, NameCollisionOption.ReplaceExisting);
file = await ApplicationData.Current.LocalFolder.GetFileAsync(file.Name);
pdfDocument = new PdfDocument(file.Path, Password);
pdfDocument.Pages.ToList().ForEach(x => Pages.Add(x));
}
catch (Exception ex) { throw ex; }
}
}
I want to use the InkToolbar which is in the parent control inside the TestControl
TestControl.xaml
<UserControl
x:Class="uwp.TestControl"
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:local="using:uwp_mvvm.ViewModels" xmlns:converter="using:uwp_mvvm"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<UserControl.Resources>
<converter:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
</UserControl.Resources>
<Grid x:Name="Viewport" VerticalAlignment="Top" HorizontalAlignment="Center">
<Border x:Name="ViewportBorder" Background="White" BorderThickness="2, 2, 2, 2" BorderBrush="#FF353334" />
<Image x:Name="Image" Margin="0" UseLayoutRounding="True" ManipulationMode="Scale"/>
<Canvas x:Name="SelectionCanvas" CompositeMode="MinBlend" Opacity="1" />
<InkCanvas x:Name="InkCanvas" />
</Grid>
</UserControl>
TastControl.xaml.cs
public sealed partial class TestControl : UserControl
{
private const float DPI = 256;
public PdfPage Page
{
get { return (PdfPage)GetValue(PageProperty); }
set { SetValue(PageProperty, value); }
}
public static readonly DependencyProperty PageProperty =
DependencyProperty.Register(nameof(Page), typeof(PdfPage), typeof(TestControl), new PropertyMetadata(null, new PropertyChangedCallback(OnPageChanged)));
private static void OnPageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (object.Equals(e.NewValue, e.OldValue) || e.NewValue is null)
return;
d.RegisterPropertyChangedCallback(PageProperty, CapturePage);
}
private static void CapturePage(DependencyObject sender, DependencyProperty dp) => (sender as TestControl).RenderPage(sender.GetValue(dp) as PdfPage);
public InkToolbar InkToolbarControl
{
get { return (InkToolbar)GetValue(InkToolbarControlProperty); }
set { SetValue(InkToolbarControlProperty, value); }
}
public static readonly DependencyProperty InkToolbarControlProperty =
DependencyProperty.Register(nameof(InkToolbarControl), typeof(InkToolbar), typeof(TestControl), new PropertyMetadata(null));
public TestControl()
{
this.InitializeComponent();
ConfigureInkCanvas();
}
private void ConfigureInkCanvas()
{
InkCanvas.InkPresenter.InputDeviceTypes = CoreInputDeviceTypes.Mouse | CoreInputDeviceTypes.Pen | CoreInputDeviceTypes.Touch;
InkCanvas.InkPresenter.InputProcessingConfiguration.Mode = InkInputProcessingMode.None;
InkCanvas.InkPresenter.UpdateDefaultDrawingAttributes(
new InkDrawingAttributes
{
IgnorePressure = false,
FitToCurve = true,
Color = Colors.Black,
PenTip = PenTipShape.Circle
});
InkCanvas.InkPresenter.UnprocessedInput.PointerEntered -= InkCanvasUnprocessedInputPointerEntered;
InkCanvas.InkPresenter.UnprocessedInput.PointerEntered += InkCanvasUnprocessedInputPointerEntered;
InkCanvas.InkPresenter.UnprocessedInput.PointerExited -= InkCanvasUnprocessedInputPointerExited;
InkCanvas.InkPresenter.UnprocessedInput.PointerExited += InkCanvasUnprocessedInputPointerExited;
}
private void InkCanvasUnprocessedInputPointerExited(InkUnprocessedInput sender, PointerEventArgs args)
{
//InkCanvas.InkPresenter.InputProcessingConfiguration.Mode = InkInputProcessingMode.Inking;
//InkToolbarControl.TargetInkCanvas = InkCanvas;
}
private void InkCanvasUnprocessedInputPointerEntered(InkUnprocessedInput sender, PointerEventArgs args)
{
//InkCanvas.InkPresenter.InputProcessingConfiguration.Mode = InkInputProcessingMode.None;
//InkToolbarControl.TargetInkCanvas = null;
}
private void RenderPage(PdfPage page, float dpi = DPI)
{
if (page is null)
return;
this.DataContext = page;
var width = (DataContext as PdfPage).Width;
var height = (DataContext as PdfPage).Height;
var writableBitmap = new WriteableBitmap((int)(width / 72f * dpi), (int)(height / 72f * dpi));
(DataContext as PdfPage).Render(writableBitmap, PageOrientations.Normal, RenderingFlags.Annotations);
Image.Width = width;
Image.Height = height;
Image.Source = writableBitmap;
SelectionCanvas.Width = width;
SelectionCanvas.Height = height;
InkCanvas.Width = width;
InkCanvas.Height = height;
Canvas.SetZIndex(Image, 0);
ConfigureInkCanvas();
}
}
I tried to use a DependencyProperty to send the InkToolbar to the TestControl but it didn't seem to work.
Could someone please help me with this? I'm not sure whether it is possible to set the TargetInkCanvas like this also. So, if there is a better approach for this any suggestions are also appreciated.
Any help is much appreciated. Thanks.
Access InkToolbar placed in parent element from programmatically generated child elements
Above solution that use DependencyProperty to pass parent InkToolBar is correct. However you bind wrong value for InkToolbarControl property.
Please bind ElementName without path directly.
<local:TestControl
x:Name="TestControl"
Margin="4,4"
InkToolbarControl="{Binding ElementName=InkToolbar}" />
Then update InkCanvasUnprocessedInputPointerExited and InkCanvasUnprocessedInputPointerEntered process logic.
private void InkCanvasUnprocessedInputPointerExited(InkUnprocessedInput sender, PointerEventArgs args)
{
InkCanvas.InkPresenter.InputProcessingConfiguration.Mode = InkInputProcessingMode.Inking;
InkToolbarControl.TargetInkCanvas = null;
}
private void InkCanvasUnprocessedInputPointerEntered(InkUnprocessedInput sender, PointerEventArgs args)
{
InkCanvas.InkPresenter.InputProcessingConfiguration.Mode = InkInputProcessingMode.None;
InkToolbarControl.TargetInkCanvas = InkCanvas;
}

Cannot Binding ImageSource in Content Dialog UWP

I put image in Content Dialog but I cannot see any image fetched from the source. It seems that the image source cannot binding from the view model. However it works well with Page
This is my XAML of Content Dialog
<ContentDialog
x:Class="SmartEducation.App.Teacher.ContentViewer.Views.SketchDetailPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SmartEducation.App.Teacher.ContentViewer.Views"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:uwpControls="using:Microsoft.Toolkit.Uwp.UI.Controls"
mc:Ignorable="d"
Title="Student's Sketch"
CloseButtonText="Cancel"
DefaultButton="Primary"
Background="White" Width="750" Height="500">
<RelativePanel>
<ScrollViewer x:Name="scrollView" ZoomMode="Enabled" DoubleTapped="ScrollViewer_DoubleTapped" HorizontalScrollBarVisibility="Visible" HorizontalScrollMode="Enabled" MinZoomFactor="1">
<StackPanel Background="White" Width="750" Height="500">
<Image Name="imgSketch" Source="{Binding ImageUri}"/>
</StackPanel>
</ScrollViewer>
</RelativePanel>
I already add ViewModel to DataContext in my xaml.cs
private SketchDetailPageViewModel ViewModel
{
get { return DataContext as SketchDetailPageViewModel; }
}
public SketchDetailPage()
{
this.InitializeComponent();
}
I put the ImageUri in my ViewModel
private string _imgContent;
public string ImageUri
{
get { return _imgContent; }
set
{
_imgContent = value;
OnPropertyChanged(nameof(ImageUri));
}
}
Firstly, please make sure the ImageUri has an image resource reference. In your xaml.cs code, just providing a ViewModel property by your following code can not set the dialog's data context, so it will not get the image source.
private SketchDetailPageViewModel ViewModel
{
get { return DataContext as SketchDetailPageViewModel; }
}
You can just configure the dialog's data context by the following code in the dialog's xaml.cs,
public SketchDetailPage()
{
this.InitializeComponent();
this.DataContext = new SketchDetailPageViewModel() { ImageUri= "ms-appx:///Assets/Image.png" };
}
If you put the image source in the ViewModel. Such as,
private string _imgContent= "ms-appx:///Assets/Image.png";
public string ImageUri
{
get { return _imgContent; }
set
{
_imgContent = value;
OnPropertyChanged(nameof(ImageUri));
}
}
Then you can set the page data context on the XAML of Content Dialog,
<ContentDialog
...
Background="White" Width="750" Height="500">
<ContentDialog.DataContext>
<local:SketchDetailPageViewModel/>
</ContentDialog.DataContext>
<RelativePanel>
<ScrollViewer x:Name="scrollView" ZoomMode="Enabled"
DoubleTapped="ScrollViewer_DoubleTapped"
HorizontalScrollBarVisibility="Visible"
HorizontalScrollMode="Enabled"
MinZoomFactor="1">
<StackPanel Background="White" Width="750" Height="500">
<Image Name="imgSketch" Source="{Binding ImageUri}"/>
</StackPanel>
</ScrollViewer>
</RelativePanel>
</ContentDialog>
Or you can set the data context in the xaml.cs,
public SketchDetailPage()
{
this.InitializeComponent();
this.DataContext = new SketchDetailPageViewModel();
}
------ Update ------
but the binding image uri doesn't change although image uri of source change
If you want to change the image by changing the image uri, you can expose the dialog's data context as the following code, meanwhile, your SketchDetailPageViewModel should implement the INotifyPropertyChanged interface. It seems you have implement the interface, here is a simple example,
SketchDetailPageViewModel class,
internal class SketchDetailPageViewModel : INotifyPropertyChanged
{
private string _imgContent;
public string ImageUri
{
get { return _imgContent; }
set
{
_imgContent = value;
OnPropertyChanged(nameof(ImageUri));
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
class SketchDetailPage : ContentDialog,
public SketchDetailPage()
{
this.InitializeComponent();
this.DataContext = new SketchDetailPageViewModel() { ImageUri= "ms-appx:///Assets/Image.png" };
}
internal SketchDetailPageViewModel ViewModel
{
get { return DataContext as SketchDetailPageViewModel; }
}
you can change the image when you use the SketchDetailPage dialog,
private async void Button_Click(object sender, RoutedEventArgs e)
{
SketchDetailPage dialog = new SketchDetailPage();
//change the dialog image
dialog.ViewModel.ImageUri = "ms-appx:///Assets/StoreLogo.png";
await dialog.ShowAsync();
}

wpf: trouble binding to subclass

I have problems understanding the binding to a property in a subclass.
This is my code:
MainWindow.XAML
<Window x:Class="Datagrid_vs_Database.MainWindow"
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:local="clr-namespace:Datagrid_vs_Database"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel>
<TextBlock x:Name="txtPath" Text="{Binding Path=CurrentDatabase.FullFilePath, UpdateSourceTrigger=PropertyChanged}"/>
<Button Command="{Binding openFileBrowser}" Content="New Database"/>
</StackPanel>
</Grid>
Manager.cs
public class Manager
{
private static readonly Manager instance = new Manager();
public static Manager Instance { get { return instance; } }
public IComOpenFileBrowser openFileBrowser { get; private set; }
MainWindow mainWindow;
public Database CurrentDatabase;
private Manager()
{
openFileBrowser = new IComOpenFileBrowser(SaveFileDialog);
CurrentDatabase = new Database();
mainWindow = new MainWindow();
mainWindow.DataContext = this;
mainWindow.Show();
}
private void SaveFileDialog()
{
var sfd = new SaveFileDialog();
sfd.Title = "Choose a filename and a directory to store the new database";
sfd.Filter = "SQLite Database (*.sqlite)|*.sqlite";
if (sfd.ShowDialog() == true)
{
CurrentDatabase.FullFilePath = sfd.FileName;
}
}
}
database.cs
public class Database : INotifyPropertyChanged
{
private string _FullFilePath;
public string FullFilePath {
get {
return _FullFilePath;
}
set { _FullFilePath = value;
NotifyPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
The thing is when I click on the Button, the SaveFileDialog appears, but when I type in a name and click OK, the Filename does not appear in the Textbox.
BUT: When I set mainWindow.txtPath.DataContext = CurrentDatabase; and delete the "CurrentDatabase." from the XAML code then it works.
I thought that it's correct to set the DataContext of the whole window to the manager class and then access the subclass in XAML by ..{Binding Path= CurrentDatabase.FullFilePath}..
But obviously thats not the case.
Can anybody tell my what I'm misunderstanding here?

Displayed image in UI locks the source file

I have a DataTemplate which was created from here:
ComboBoxes sharing Observable Collection keeps breaking
<UserControl.Resources>
<DataTemplate x:Key="ImageItemTemplate">
<StackPanel Orientation="Horizontal">
<Image Height="44" Source="{Binding Path}"/>
<Label Content="{Binding Name}" VerticalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</UserControl.Resources>
<ComboBox x:Name="image1" ItemTemplate="{StaticResource ImageItemTemplate}"/>
Code:
public ObservableCollection<ImageItem> images = new ObservableCollection<ImageItem>();
Generic.ImportGrfx(tabID, image1, images);
public static void ImportGrfx(string tabID, ComboBox combo, ObservableCollection<ImageItem> items)
{
items.Clear();
try
{
string root = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
var files = Directory.GetFiles(Path.Combine(root, "input\\" + tabID), "*.png");
foreach (var file in files)
{
ImageItem item = new ImageItem();
item.Path = file;
item.Name = Path.GetFileName(file).Remove(Path.GetFileName(file).Length - 4);
items.Add(item);
}
}
catch (Exception) { }
combo.ItemsSource = items;
}
public class ImageItem
{
public string Path { get; set; }
public string Name { get; set; }
}
The problem I am having is binding these images to the datatemplate, "locks" the image source. Meaning I can't edit the images while the program is running... I would get an error stating the image is in use. Is there a way to fix this?
Here's a skeleton of an Image that will get updated whenever you modify it from outside.
you set the source, it copies it to a temp path and loads the image from there
it watches for changes in initial image and updates itself again
rinse and repeat :D
You can, not use the auto-update feature if you only need the ability to edit the image from outside.
It's really basic so feel free to improve ...
Code:
using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
namespace WpfApplication4
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
DynamicImage1.SetSource(#"d:\Untitled.png");
}
}
internal class DynamicImage : Image
{
private string _name;
private FileSystemWatcher _watcher;
public void SetSource(string fileName)
{
if (fileName == null) throw new ArgumentNullException("fileName");
if (_watcher != null)
{
_watcher.Changed -= watcher_Changed;
_watcher.Dispose();
}
string path = Path.GetDirectoryName(fileName);
_watcher = new FileSystemWatcher(path);
_watcher.EnableRaisingEvents = true;
_watcher.Changed += watcher_Changed;
_name = fileName;
string tempFileName = Path.GetTempFileName();
File.Copy(fileName, tempFileName, true);
Source = new BitmapImage(new Uri(tempFileName));
}
private void watcher_Changed(object sender, FileSystemEventArgs e)
{
bool b = string.Equals(e.FullPath, _name, StringComparison.InvariantCultureIgnoreCase);
if (b)
{
string tempFileName = Path.GetTempFileName();
File.Copy(e.FullPath, tempFileName, true);
Dispatcher.BeginInvoke((Action) (() => { Source = new BitmapImage(new Uri(tempFileName)); }));
_name = e.FullPath;
}
}
}
}
XAML:
<Window x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfApplication4="clr-namespace:WpfApplication4"
Title="MainWindow" Height="350" Width="525">
<Grid>
<wpfApplication4:DynamicImage x:Name="DynamicImage1" />
</Grid>
</Window>

Image not displaying XAML

I created my own button that has Icon on the side and text on the other but the problem is the image is not displaying. did i miss something here? any help would be appreciated. TIA
This is the XAML of the control.
<UserControl x:Name="QButtonControl"
x:Class="CommonLayout.QButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CommonLayout"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="36"
d:DesignWidth="145" MinWidth="145" MinHeight="36" Loaded="QButtonControl_Loaded">
<Grid PointerEntered="Grid_PointerEntered_1" PointerExited="Grid_PointerExited_1" MinWidth="145" MinHeight="36" Background="#FFDCD1D1">
<TextBlock x:Name="btnLabel" Height="20" Margin="36,8,4,8" TextWrapping="Wrap" Text="Text Here" VerticalAlignment="Center" FontSize="18.667" Width="105"/>
<Image x:Name="img" HorizontalAlignment="Left" Height="27" Margin="1,4,0,0" VerticalAlignment="Top" Width="29"/>
</Grid>
</UserControl>
This is code behind the control.
public sealed partial class QButton : UserControl
{
private ImageSource iconDefault;
private Brush hoverBrush = new SolidColorBrush(Color.FromArgb(255, 228, 228, 228));
public string Text
{
get
{
return btnLabel.Text;
}
set
{
btnLabel.Text = value;
}
}
public ImageSource Icon
{
get
{
return iconDefault;
}
set
{
iconDefault = value;
img.Source = value;
}
}
public Brush HoverBrush
{
get
{
return hoverBrush;
}
set
{
hoverBrush = value;
}
}
public QButton()
{
this.InitializeComponent();
}
private void Grid_PointerEntered_1(object sender, PointerRoutedEventArgs e)
{
btnLabel.Foreground = HoverBrush;
}
private void Grid_PointerExited_1(object sender, PointerRoutedEventArgs e)
{
btnLabel.Foreground = Foreground;
}
private void QButtonControl_Loaded(object sender, RoutedEventArgs e)
{
img.Source = iconDefault;
}
}
First of all, do not use a hard coded file path to the image.
Windows Store apps run in a sandbox, so you will not be able to get to any arbitrary file location when you deploy your app.
Second, you can't use backslashes in Image URI. The backslashes are the technical reason you are setting the error you are getting. But just changing to forward slashes in not the answer.
Access Image in XAML
If you add an image to your projects /Assets folder, you can use XAML like this to show it in QButton.
<local:QButton x:Name='qButton1'
Icon='/assets/jellyfish.jpg' />
In Code
To change the Icon in code.
public MainPage()
{
this.InitializeComponent();
this.Loaded += MainPage_Loaded;
}
private async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/shrimp.jpg"));
var fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
var image = new BitmapImage();
image.SetSource(fileStream);
qButton1.Icon = image;
}
If you want the user to choose the Image from their computer at runtime, look at the File Pickers.
MSDN file pickers
Are you forgetting to set the Icon property?
This worked for me
<local:QButton Icon="C:\Users\Public\Pictures\Sample Pictures\Penguins.jpg" />
This worked as well
public QButton()
{
this.InitializeComponent();
Uri imageUri = new Uri(#"C:\Users\Public\Pictures\Sample Pictures\Penguins.jpg");
BitmapImage image = new BitmapImage(imageUri);
this.Icon = image;
}

Categories

Resources