At first I want to say that i searched on internet and I didn't found anything. I would like to make a dynamic song list, that when user adds a song, new object will be added with name and lenght and when he selects this song he would get a path to the selected song. Here is code to understand better:
XAML:
<Window x:Class="ListBox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ListBox x:Name="SongList" HorizontalAlignment="Left" Height="278" Margin="10,10,0,0" VerticalAlignment="Top" Width="248"/>
<TextBlock HorizontalAlignment="Left" Margin="287,124,0,0" TextWrapping="Wrap" Text="Path" VerticalAlignment="Top" Width="194" Height="22"/>
<Label Content="Song Path" HorizontalAlignment="Left" Margin="287,98,0,0" VerticalAlignment="Top" Width="194"/>
<Button Content="Add Song" HorizontalAlignment="Left" Margin="10,293,0,0" VerticalAlignment="Top" Width="132" Click="Button_Click"/>
</Grid>
and code:
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace ListBox
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openfile = new OpenFileDialog();
openfile.DefaultExt = ".mp3";
openfile.Filter = "mp3 | *.mp3";
Nullable<bool> result = openfile.ShowDialog();
if (result == true)
{
String file = openfile.FileName;
FileInfo fileinfo = new FileInfo(file);
SongList.Items.Add(fileinfo.Name);
}
}
}
}
so where the "Path" text box is I would like to get current selected song path. Is it possible to make with ItemBox or I need to make array that will save all paths?
I think you should use for your songs, because you're writing a WPF application, an ObservableCollection of your song objects, in order to have a proper ListBox with your updated objects.
Then, you have to create a proper Song class with its own properties, like the SongName or the SongPath. In this class, you will implement the INotifyPropertyChanged interface
and, for each property, you will raise an appropriate OnPropertyChanged event.
With this implementation, once you load a song and add it to the songs list, your ListBox will show the updated collection accordingly.
Further info about the ObservableCollection here.
If you want to have a look at a code sample, in this answer I written an example of developing an ObservableCollection.
at first you might want to have a look at MVVM programming. The concept is not that easy to understand, even harder to apply but once you got it you will be able to create good UI in no-time and it's especially perfect for what you are trying to do.
Now to your problem. FileInfo.Name only stores the file name not the path, so if you don't store the path separately, you won't be able to get it back from just the file name.
KillaKem's solution seems pretty good, however I wouldn't recommend using the Tag property for this. Just create a Collections::Generic::List (please, don't use arrays) class member to store the paths and then use the selectedIndexChange Event to update the PathSearchBox.
using MVVM you could just link the ListBox to a Dictionary which stores both, path and filename and just display the Filename, feel free to research MVVM a bit yourself.
Regards,
Xaser
You could try something along the lines of this,
XAML:
<Window x:Class="ListBox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ListBox x:Name="SongList" HorizontalAlignment="Left" Height="278" Margin="10,10,0,0" VerticalAlignment="Top" Width="248"/>
<TextBlock HorizontalAlignment="Left" Margin="287,124,0,0" TextWrapping="Wrap" Text="Path" VerticalAlignment="Top" Width="194" Height="22"/>
<Label Name ="pathLabel" Content="Song Path" HorizontalAlignment="Left" Margin="287,98,0,0" VerticalAlignment="Top" Width="194"/>
<Button Content="Add Song" HorizontalAlignment="Left" Margin="10,293,0,0" VerticalAlignment="Top" Width="132" Click="Button_Click"/>
</Grid>
Back Code:
namespace ListBox
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openfile = new OpenFileDialog();
openfile.DefaultExt = ".mp3";
openfile.Filter = "mp3 | *.mp3";
Nullable<bool> result = openfile.ShowDialog();
if (result == true)
{
String file = openfile.FileName;
FileInfo fileinfo = new FileInfo(file);
SongList.Items.Add(fileinfo.Name);
var pathList = SongList.Tag as List<string>;
pathList.Add(fileinfo.DirectoryName);
SongList.Tag = pathList;
}
}
private void Selection_Changed(object sender, EventArgs e)
{
var myListBox = sender as ListBox;
var myPathList = myListBox.Tag as List<string>;
var filePath = myPathList[myListBox.SelectedIndex];
pathLabel.Content = filePath;
}
}
}
Haven't tested the code but it should be working or close to working.
These is a SelectionChanged event in the listbox you can use. But i would recommend using bi
Related
I'm using Material design. I created a color picker to choose the color the user wants, after the user chooses the color and theme.
I want to save these settings into a text file on the disk. I don't know how can I convert these types to a list for the string which can I use for reading theme that is saved :
private void MyColorPicker1_PreviewMouseMove(object sender, MouseEventArgs e)
{
string filepath = #"C:\Themses";
if (e.LeftButton == MouseButtonState.Pressed)
{
ITheme theme = _paletteHelper.GetTheme();
theme.SetPrimaryColor(Color.FromRgb(MyColorPicker1.Color.R, MyColorPicker1.Color.G, MyColorPicker1.Color.B)); //red
var Test = theme.GetBaseTheme();
// something here to write all setting inside of ITheme into the text file
//
_paletteHelper.SetTheme(theme);
}
}
How can I do that?
Full XAML:
<Window x:Class="WpfApp5.SettingThemsWins.MaterialThemSettingy"
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:WpfApp5.SettingThemsWins"
mc:Ignorable="d"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
Background="{DynamicResource MaterialDesignPaper}"
Title="Setting" Height="607" Width="1144" WindowStartupLocation="CenterScreen">
<Grid>
<materialDesign:ColorPicker x:Name="MyColorPicker1" HorizontalAlignment="Left" Margin="20,17,0,0" VerticalAlignment="Top" Height="353" Width="750" PreviewMouseMove="MyColorPicker1_PreviewMouseMove" />
<ToggleButton x:Name="ThemeActivationsBtn" Style="{StaticResource MaterialDesignSwitchToggleButton}" ToolTip="Activation Of Dark Theme" IsChecked="False" Margin="110,380,0,0" Click="ThemeActivationsBtn_Click" HorizontalAlignment="Left" Width="63" Height="27" VerticalAlignment="Top" />
<Label Content="Dark Theme :" HorizontalAlignment="Left" Height="24" Margin="20,382,0,0" VerticalAlignment="Top" Width="85"/>
<Button x:Name="SaverThemy" Content="Save Theme" HorizontalAlignment="Left" Margin="200,375,0,0" VerticalAlignment="Top" Width="170" Click="SaverThemy_Click"/>
</Grid>
</Window>
Code behind:
using MaterialDesignThemes.Wpf;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace WpfApp5.SettingThemsWins
{
/// <summary>
/// Interaction logic for MaterialThemSettingy.xaml
/// </summary>
public partial class MaterialThemSettingy : Window
{
private readonly PaletteHelper _paletteHelper = new PaletteHelper();
bool isDark;
public MaterialThemSettingy()
{
InitializeComponent();
//EmptySampleWind.Window1 window1 = new EmptySampleWind.Window1();
//window1.Show();
}
public static IEnumerable<string> SortByLength(IEnumerable<string> e)
{
// Use LINQ to sort the array received and return a copy.
var sorted = from s in e
orderby s.Length ascending
select s;
return sorted;
}
private void MyColorPicker1_PreviewMouseMove(object sender, MouseEventArgs e)
{
string filepath = #"C:\Themses";
if (e.LeftButton == MouseButtonState.Pressed)
{
ITheme theme = _paletteHelper.GetTheme();
theme.SetPrimaryColor(Color.FromRgb(MyColorPicker1.Color.R, MyColorPicker1.Color.G, MyColorPicker1.Color.B)); //red
var Test = theme.GetBaseTheme();
// something here to write all setting inside of ITheme into the text file
//
_paletteHelper.SetTheme(theme);
}
}
private void ThemeActivationsBtn_Click(object sender, RoutedEventArgs e)
{
isDark = (bool)ThemeActivationsBtn.IsChecked;
if (isDark)
{
ITheme theme = _paletteHelper.GetTheme();
IBaseTheme baseTheme = isDark ? new MaterialDesignDarkTheme() : (IBaseTheme)new MaterialDesignLightTheme();
theme.SetBaseTheme(baseTheme);
_paletteHelper.SetTheme(theme);
}
else
{
ITheme theme = _paletteHelper.GetTheme();
IBaseTheme baseTheme = isDark ? new MaterialDesignDarkTheme() : (IBaseTheme)new MaterialDesignLightTheme();
theme.SetBaseTheme(baseTheme);
_paletteHelper.SetTheme(theme);
}
}
}
}
I use DataTemplate to repeatedly generate the content of my ListBox.
The xaml code is as below:
<DataTemplate x:Key="singleUnit">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding fileName}" FontSize="20" Foreground="{Binding color}" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<TextBlock/>
</StackPanel>
</DataTemplate>
<ListBox Name="MyListBox" Width="300" Height="600">
</ListBox>
And the cs code is:
private void Show()
{
const int TotalCount = 100;
for (int i = 0; i < TotalCount; i++)
{
ContentControl cc = new ContentControl();
cc.ContentTemplate = this.Resources["singleUnit"] as DataTemplate;
DataModel dm = new DataModel();
dm.fileName = "myfile" + i;
dm.color = new SolidColorBrush(Colors.Blue);
cc.Content = dm;
MyListBox.Items.Add(cc);
}
MyListBox.ScrollIntoView(MyListBox.Items[TotalCount / 2]);
}
Above code will generate below UI:
And I hope to change all the item's color: currently each item, the fileName's foreground color is blue. And I hope to change it to like green when the button is pressed.
This is like that user changes the color theme with some selection operation. And when the color changes, all the other things should be not changed, e.g. the position of the scroll bar.
The difficulty is that I use template to generate the content, and how to iterate each item and modify it.
I put the workable demo code on my Github:
https://github.com/tomxue/ChangeListBox.git
You could start from it.
Thanks!
I made your code work but it is still not perfectly right as you should have per each view a view-model and bind between them.
Your MainForm - should have a MainFormViewModel.
Your File Items - should have VmFile (or ViewModelFile as I wrote in the example)
You should be using ICommand to bind the button and not by having an event as you did.
Shortly put, I don't think you are working correct with MVVM, I advise you to read more about MVVM.
Copy to your .xaml file:
<Window x:Class="WpfApp14.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:WpfApp14"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<ListBox Name="MyListBox" Width="300" Height="600">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FileName}" FontSize="20" Foreground="{Binding Color}"
HorizontalAlignment="Left" VerticalAlignment="Top"/>
<TextBlock/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Content="Change color theme" HorizontalAlignment="Left" Margin="56,126,0,0" VerticalAlignment="Top" Width="164" Click="Button_Click" Height="36"/>
</Grid>
</Window>
Copy to your .cs file:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApp14
{
public class ViewModelFile : INotifyPropertyChanged
{
private string filename;
private SolidColorBrush solidColorBrush;
public event PropertyChangedEventHandler PropertyChanged;
public string FileName
{
get =>filename;
set
{
filename = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(FileName)));
}
}
public SolidColorBrush Color
{
get => solidColorBrush;
set
{
solidColorBrush = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Color)));
}
}
}
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Refresh();
}
private void Refresh()
{
const int TotalCount = 100;
for (int i = 0; i < TotalCount; i++)
{
ViewModelFile vm = new ViewModelFile
{
FileName = "myfile" + i,
Color = new SolidColorBrush(Colors.Blue)
};
MyListBox.Items.Add(vm);
}
MyListBox.ScrollIntoView(MyListBox.Items[TotalCount / 2]);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
// Do something to change all fileName items' forground color to red.
// For example if user changes the color theme, and we should just change some UI color
// while not changing any other part, e.g. the position of scrollbar
foreach (var item in MyListBox.Items)
((ViewModelFile)item).Color = new SolidColorBrush(Colors.Red);
}
}
}
I'm making an image viewer. I have a mouse event that is supposed to trigger when an image (or child of StackPanel in this case), is clicked. The event is triggered as intended. The problem is, since the pathfile of the images is different depending on whichever is selected (in which directory, etc.), I just don't know how to get the pathfile of the specific image that is currently clicked on. The directory depends on whichever folder is loaded, so the pathfile could be different everytime.
If you scroll all the way down to Image_Load(), I have the Pic.Fill which is a reference to the rectangle that is being filled with the image. I'm trying to find the first parameter for Uri(_,_), which is supposed to be where the #"path" of the current image is.
using System;
using System.IO;
using Microsoft.Win32;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Drawing;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Forms;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApp1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
FolderBrowserDialog fbd = new FolderBrowserDialog();
List<string> paths = new List<string>();
string[] extension = new[] { ".jpg", ".png", ".jpeg", ".gif", ".bmp", ".tif", ".tiff" };
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e) {
if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string[] files = Directory.GetFiles(fbd.SelectedPath);
FileLocation.Text = fbd.SelectedPath;
}
}
private void OpenButton_Click(object sender, RoutedEventArgs e)
{
LoadPhotos();
}
private void LoadPhotos()
{
try
{
DirectoryInfo di = new DirectoryInfo(fbd.SelectedPath);
foreach (var fi in di.GetFiles().Where(f => extension.Contains(f.Extension.ToLower())).ToArray())
{
paths.Add(fi.FullName);
}
Photos.ItemsSource = paths;
} catch (Exception e)
{
Console.WriteLine("File not found.", e.Source);
}
}
private void Image_Load(object sender, MouseButtonEventArgs e)
{
// What is the reference here?
Pic.Fill = new ImageBrush { ImageSource = new BitmapImage(new Uri(/*Insert pathfile here*/, UriKind.Absolute)) };
}
}
}
Here's my .xaml. I've analyzed it to see a reference but the only thing that stands out is the Image Source, which I've tagged with a comment. It's set to { Binding . } which I'm going to assume means, whatever image is referenced. But how do I connect that variable reference to my Image_Load()? (which is declared on the instantiation of ListBox)
<Window x:Class="WpfApp1.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:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="1081" Width="1720.5">
<Grid Margin="0,0,2,-0.578">
<Button x:Name="OpenButton" Content="Load" HorizontalAlignment="Left" Height="44" Margin="1166.374,932.042,0,0" VerticalAlignment="Top" Width="145.666" Background="#FFDDDDDD" FontSize="24" Click="OpenButton_Click"/>
<Button x:Name="BrowseButton" Content="Browse" HorizontalAlignment="Left" Height="44" Margin="58.666,932.042,0,0" VerticalAlignment="Top" Width="134.166" Background="#FFDDDDDD" FontSize="24" Click="Button_Click"/>
<Rectangle x:Name="Pic" Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="878.767" Margin="58.666,34.733,0,0" Stroke="Black" VerticalAlignment="Top" Width="1253.374"/>
<ScrollViewer VerticalScrollBarVisibility="Visible" Width="327.46" HorizontalAlignment="Left" Margin="1339.04,34.733,0,137.078" RenderTransformOrigin="0.5,0.5" >
<StackPanel Width="327.46" RenderTransformOrigin="0.516,0.496" HorizontalAlignment="Left" VerticalAlignment="Center" Height="878.085">
<ListBox x:Name="Photos"
Grid.Row="2" Grid.Column="1" Height="876" PreviewMouseDown="Image_Load">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Width="300" Height="100">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
/* Image Source? */
<Image Source="{Binding .}" Grid.Column="0"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</ScrollViewer>
<TextBlock x:Name="FileLocation" HorizontalAlignment="Left" Height="44" Margin="192.832,948.542,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="973.542" Foreground="#FF515151" TextAlignment="Center" FontSize="14"/>
</Grid>
</Window>
I've been learning on the way using Blend-- some youtube tutorials here and there. I've tried to look for a solution online but all the questions about it usually involve a static and specific directory. This is my first program and the only thing I need is that darn path file reference. There are so many object reference so I just don't even know how to wrap my head around it, being so unfamiliar with these classes. Some assistance would be very much appreciated! :)
In a WPF application, I have a webbrowser called WebBrowser1. This refers to an HTML page which contains a TextArea to which users can input text.
<html>
<body>
<textarea class="myStudentInput" id="myStudentInput1">
Text to be copied
</textarea>
</body>
</html>
I wish to get this text and potentially also set this text.
I have tried something similar to the javascript way of writing it:
document.getElementById("myStudentOutput1").innerHTML;
such as
HtmlElement textArea = webBrowser1.Document.All["myStudentInput1"];
dynamic textArea = WebBrowser1.Document.GetElementsByID("myStudentInput1").InnerText;
but it doesn't work.
The following solution in Visual Studio 2015 WPF Application works for me.
First, add a reference to the Microsoft HTML COM Library. This is on the COM tab, when you do an "Add Reference" in your project.
Then add the code:
<Window x:Class="WpfApplication3.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:WpfApplication3"
mc:Ignorable="d"
Title="MainWindow" Height="600" Width="800">
<Grid>
<WebBrowser x:Name="WebBrowser1" HorizontalAlignment="Left" Height="480" Margin="10,10,0,0" VerticalAlignment="Top" Width="770" Source="E:\Others\Dropbox\Programming\Questions.html"/>
<Button x:Name="mySetQuestionButton" Content="Set Question" HorizontalAlignment="Left" Margin="200,520,0,0" VerticalAlignment="Top" Width="75" Click="mySetQuestion"/>
<Button x:Name="myGetAnswerButton" Content="Get Answer" HorizontalAlignment="Left" Margin="350,520,0,0" VerticalAlignment="Top" Width="75" Click="myGetAnswer"/>
<TextBlock x:Name="textBlock" HorizontalAlignment="Left" Margin="600,520,0,0" TextWrapping="Wrap" Text="Hello2" VerticalAlignment="Top"/>
</Grid>
</Window>
and
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication3
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void mySetQuestion(object sender, EventArgs e)
{
mshtml.HTMLDocument document = (mshtml.HTMLDocument)WebBrowser1.Document;
mshtml.IHTMLElement textArea = document.getElementById("myQuestion1");
textArea.innerHTML = "What is 1+1?";
}
private void myGetAnswer(object sender, EventArgs e)
{
mshtml.HTMLDocument document = (mshtml.HTMLDocument)WebBrowser1.Document;
mshtml.IHTMLElement textArea = document.getElementById("myStudentInput1");
textBlock.Text = textArea.innerHTML;
}
}
}
but it doesn't work.
I have no idea what that could possibly mean. All you can get is a code snippet that does work:
public partial class Form1 : Form {
private WebBrowser webBrowser1;
private Button button1;
public Form1() {
button1 = new Button { Text = "Test" };
button1.Click += button1_Click;
this.Controls.Add(button1);
webBrowser1 = new WebBrowser { Dock = DockStyle.Fill };
webBrowser1.DocumentText = #"<html><body><textarea class=""myStudentInput"" id=""myStudentInput1"">Text to be copied</textarea></body></html>";
this.Controls.Add(webBrowser1);
}
private void button1_Click(object sender, EventArgs e) {
var elem = webBrowser1.Document.GetElementById("myStudentInput1");
MessageBox.Show(elem.InnerText);
}
}
Which produces:
I'm using ImageTools for Silverlight to load a JPG image, but the decoded image quality is BAD (no anti-aliasing, see the second image in the red square).
Here is my code:
OpenFileDialog dlg = new OpenFileDialog();
if (dlg.ShowDialog() == true)
{
var stream = dlg.File.OpenRead();
var newImg = new ExtendedImage(); // ExtendedImage is a ImageTools Api class
var d= new ImageTools.IO.Jpeg.JpegDecoder();
d.Decode(newImg, stream);
image1.Source = newImg.ToBitmap(); //image1 is a System.Windows.Controls.Image
}
Source image
Bad result
Observations
If I set image1.source directly to a URL from the original image, the image is rendered correctly!
Is this a bug in the ImageTools API?
The problem is posted on Codeplex, but it doesn't have any answers.
If I rewrite my code, I get the same result.
XAML
<UserControl x:Class="JPGDecoder.MainPage"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<Image Height="120" HorizontalAlignment="Left" Margin="46,75,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Top" Width="160" Source="/JPGDecoder;component/Images/org.jpg" />
<Image Height="120" HorizontalAlignment="Left" Margin="212,75,0,0" Name="image2" Stretch="Fill" VerticalAlignment="Top" Width="160" />
<Button Content="Decode JPG from File Stream" Height="23" HorizontalAlignment="Left" Margin="44,25,0,0" Name="button1" VerticalAlignment="Top" Width="192" Click="button1_Click" />
</Grid>
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using ImageTools;
namespace JPGDecoder
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
var dlg = new OpenFileDialog();
if (dlg.ShowDialog()==true)
{
var stream = dlg.File.OpenRead();
var newImg = new ExtendedImage();
var d = new ImageTools.IO.Jpeg.JpegDecoder();
d.Decode(newImg, stream);
image2.Source = newImg.ToBitmap();
}
}
}
}
Result
Mmm... I think it would be a good idea if you post a question to the ImageTool codeplex forum, this author used to answer quite fast.
Have you checked the samples from his site?
Usually I had no problems with this library.
Cheers
Braulio
ImageTools does not support antialising, so I got FJCore from Subversion and ran the sample app.
First test same result, bad quality.
Looking at the source code, I found this code block:
// Resize
DecodedJpeg jpegOut = new DecodedJpeg(
new ImageResizer(jpegIn.Image).Resize(320, ResamplingFilters.NearestNeighbor),
jpegIn.MetaHeaders); // Retain EXIF details
and changed it to this:
//Resize
DecodedJpeg jpegOut = new DecodedJpeg(
new ImageResizer(jpegIn.Image).Resize(320, ResamplingFilters.LowpassAntiAlias),
jpegIn.MetaHeaders); // Retain EXIF details
This is the solution: ResamplingFilters.LowpassAntiAlias
Thanks everyone!!