WPF:如何将图像上传到您的项目并稍后将其用作资源
WPF: How to upload an image to your project and use it later on as a resource
我在学校学习 WPF,但我 运行 遇到了将新图像上传到我的项目的问题。
目标是能够使用文件浏览器添加图像(在运行时)。此图像应上传到项目中,文件名应保存在数据库中。它应该可以作为项目中的资源进行访问,因此我可以在列表框中显示图像。
这是我目前得到的:
查看上传发生的位置:
<Image Height="70px" Source="{Binding newImg}"/>
<Button Height="23" Name="btnLoad" VerticalAlignment="Bottom"
Width="75" Grid.Column="0" Grid.Row="1" Command="{Binding ImgUploadCommand}">_Browse</Button>
ViewModel 上传View
private string fullPath;
private BitmapImage image;
private Patient newPatient = new Patient();
private void KoppelenCommands()
{
FotoUploadCommand = new BaseCommand(FotoPatientUpload);
PatientOpslaanCommand = new BaseCommand(PatientOpslaan);
}
public ICommand FotoUploadCommand { get; set; }
public ICommand PatientOpslaanCommand { get; set; }
public void FotoPatientUpload()
{
OpenFileDialog op = new OpenFileDialog();
op.Title = "Select a picture";
op.Filter = "All supported graphics|*.jpg;*.jpeg;*.png|" +
"JPEG (*.jpg;*.jpeg)|*.jpg;*.jpeg|" +
"Portable Network Graphic (*.png)|*.png";
if (op.ShowDialog() == true)
{
image= new BitmapImage(new Uri(op.FileName));
fullPath = op.FileName;
string[] partsFileName = fullPath.Split('\');
System.Windows.MessageBox.Show(delenFileName[(partsFileName.Length - 1)]);
NewPatient.Image= partsFileName[(delenFileName.Length - 1)];
}
}
public void PatientOpslaan()
{
string destinationPath = GetDestinationPath(NewPatient.Afbeelding, "\assets\images");
File.Copy(fullPath, destinationPath, true);
//dataservice (My DS works fine, I can see the correct filename in the database but I save only the name not the Path)
PatientDataService patientDS =
new PatientDataService();
patientDS.InsertPatient(NewPatient);
}
else
{
MessageBox.Show("Niet alle velden zijn ingevuld! Een nieuwe patient moet tenminste een naam en een voornaam krijgen!", "Fout!", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
//opslaan foto in opgegeven map <<Code afkomstig van Whosebug auteur: Yashpal Singla>>
private static String GetDestinationPath(string filename, string foldername)
{
String appStartPath = System.IO.Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
appStartPath = String.Format(appStartPath + "\{0}\" + filename, foldername);
return appStartPath;
}
图像已正确保存到 bin/debug/assets/images 文件夹,但未作为资源。因为它没有保存为资源,所以我不能在我的主窗口视图中使用它,它看起来像这样:
<ListBox HorizontalContentAlignment="Center" ItemsSource="{Binding Patienten}" SelectedItem="{Binding SelectedPatient}" Grid.Column="0" Grid.Row="0">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Name="ImageNameListBox" Visibility="Collapsed"
Text="{Binding Image, StringFormat=../assets/images/{0}}" />
<Border Style="{StaticResource imageBorderStyle}" Grid.Column="0" Grid.Row="0" Height="80px" Width="80px">
<Rectangle Margin="1,-2,-2,1" Height="80px" Width="80px">
<Rectangle.Fill>
<ImageBrush ImageSource="{Binding Text, ElementName=ImageNameListBox}"/>
</Rectangle.Fill>
</Rectangle>
</Border>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
主窗口视图模型:
class MainWindowViewModel : BaseViewModel
{
private DialogService dialogService;
private ObservableCollection<Patient> patienten;
public ObservableCollection<Patient> Patienten
{
get
{
return patienten;
}
set
{
patienten = value;
NotifyPropertyChanged();
}
}
private Patient selectedPatient;
public Patient SelectedPatient {get; set;}
public MainWindowViewModel()
{
LoadingPatients();
//instantiëren DialogService als singleton
dialogService = new DialogService();
}
private void LoadingPatients()
{
//instantiëren dataservice
PatientDataService patientDS =
new PatientDataService();
Patienten = new ObservableCollection<Patient>(patientDS.GetPatienten());
}
}
请注意,我没有包含所有代码,因此我的数据上下文设置了一个您在此处看不到的 ViewModelLocator。
有什么方法可以将图像保存为资源,还是必须在启动时将 /bin/debug/assets/images 文件夹中的所有图像转换为资源?如果可以,我该怎么做?
抱歉我的英语不好,我不是母语人士
感谢那些有勇气一路读到这一行的人,感谢那些能够帮助我的人!
您可以从您的文件中将图像加载为 ImageSource
并将其绑定到您视图中的 Image
。
public class MyViewModel
{
public void LoadImage()
{
ImageSource = new BitmapImage(new Uri("assets/images/yourImage.jpg", UriKind.Relative));
}
public ImageSource ImageSource { get; set; }
}
在视图中:
<Image Source="{Binding Path=ImageSource}"></Image>
作为对评论的回答,这也适用于列表框。
视图:
<ListBox ItemsSource="{Binding Path=MyImages}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Path=ImageSource}"/>
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
ViewModel:
public class MainWindowViewModel
{
public void LoadImages()
{
var d = new DirectoryInfo("assets/images");
var images = d.GetFiles();
MyImages = images.Select(x => new MyImageModel(x.Name, new BitmapImage(new Uri(x.FullName))));
}
public IEnumerable<MyImageModel> MyImages { get; set; }
}
MyImageModel
public class MyImageModel
{
public MyImageModel(string name, ImageSource imageSource)
{
Name = name;
ImageSource = imageSource;
}
public string Name { get; set; }
public ImageSource ImageSource { get; set; }
}
我在学校学习 WPF,但我 运行 遇到了将新图像上传到我的项目的问题。
目标是能够使用文件浏览器添加图像(在运行时)。此图像应上传到项目中,文件名应保存在数据库中。它应该可以作为项目中的资源进行访问,因此我可以在列表框中显示图像。
这是我目前得到的:
查看上传发生的位置:
<Image Height="70px" Source="{Binding newImg}"/>
<Button Height="23" Name="btnLoad" VerticalAlignment="Bottom"
Width="75" Grid.Column="0" Grid.Row="1" Command="{Binding ImgUploadCommand}">_Browse</Button>
ViewModel 上传View
private string fullPath;
private BitmapImage image;
private Patient newPatient = new Patient();
private void KoppelenCommands()
{
FotoUploadCommand = new BaseCommand(FotoPatientUpload);
PatientOpslaanCommand = new BaseCommand(PatientOpslaan);
}
public ICommand FotoUploadCommand { get; set; }
public ICommand PatientOpslaanCommand { get; set; }
public void FotoPatientUpload()
{
OpenFileDialog op = new OpenFileDialog();
op.Title = "Select a picture";
op.Filter = "All supported graphics|*.jpg;*.jpeg;*.png|" +
"JPEG (*.jpg;*.jpeg)|*.jpg;*.jpeg|" +
"Portable Network Graphic (*.png)|*.png";
if (op.ShowDialog() == true)
{
image= new BitmapImage(new Uri(op.FileName));
fullPath = op.FileName;
string[] partsFileName = fullPath.Split('\');
System.Windows.MessageBox.Show(delenFileName[(partsFileName.Length - 1)]);
NewPatient.Image= partsFileName[(delenFileName.Length - 1)];
}
}
public void PatientOpslaan()
{
string destinationPath = GetDestinationPath(NewPatient.Afbeelding, "\assets\images");
File.Copy(fullPath, destinationPath, true);
//dataservice (My DS works fine, I can see the correct filename in the database but I save only the name not the Path)
PatientDataService patientDS =
new PatientDataService();
patientDS.InsertPatient(NewPatient);
}
else
{
MessageBox.Show("Niet alle velden zijn ingevuld! Een nieuwe patient moet tenminste een naam en een voornaam krijgen!", "Fout!", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
//opslaan foto in opgegeven map <<Code afkomstig van Whosebug auteur: Yashpal Singla>>
private static String GetDestinationPath(string filename, string foldername)
{
String appStartPath = System.IO.Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
appStartPath = String.Format(appStartPath + "\{0}\" + filename, foldername);
return appStartPath;
}
图像已正确保存到 bin/debug/assets/images 文件夹,但未作为资源。因为它没有保存为资源,所以我不能在我的主窗口视图中使用它,它看起来像这样:
<ListBox HorizontalContentAlignment="Center" ItemsSource="{Binding Patienten}" SelectedItem="{Binding SelectedPatient}" Grid.Column="0" Grid.Row="0">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Name="ImageNameListBox" Visibility="Collapsed"
Text="{Binding Image, StringFormat=../assets/images/{0}}" />
<Border Style="{StaticResource imageBorderStyle}" Grid.Column="0" Grid.Row="0" Height="80px" Width="80px">
<Rectangle Margin="1,-2,-2,1" Height="80px" Width="80px">
<Rectangle.Fill>
<ImageBrush ImageSource="{Binding Text, ElementName=ImageNameListBox}"/>
</Rectangle.Fill>
</Rectangle>
</Border>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
主窗口视图模型:
class MainWindowViewModel : BaseViewModel
{
private DialogService dialogService;
private ObservableCollection<Patient> patienten;
public ObservableCollection<Patient> Patienten
{
get
{
return patienten;
}
set
{
patienten = value;
NotifyPropertyChanged();
}
}
private Patient selectedPatient;
public Patient SelectedPatient {get; set;}
public MainWindowViewModel()
{
LoadingPatients();
//instantiëren DialogService als singleton
dialogService = new DialogService();
}
private void LoadingPatients()
{
//instantiëren dataservice
PatientDataService patientDS =
new PatientDataService();
Patienten = new ObservableCollection<Patient>(patientDS.GetPatienten());
}
}
请注意,我没有包含所有代码,因此我的数据上下文设置了一个您在此处看不到的 ViewModelLocator。
有什么方法可以将图像保存为资源,还是必须在启动时将 /bin/debug/assets/images 文件夹中的所有图像转换为资源?如果可以,我该怎么做?
抱歉我的英语不好,我不是母语人士
感谢那些有勇气一路读到这一行的人,感谢那些能够帮助我的人!
您可以从您的文件中将图像加载为 ImageSource
并将其绑定到您视图中的 Image
。
public class MyViewModel
{
public void LoadImage()
{
ImageSource = new BitmapImage(new Uri("assets/images/yourImage.jpg", UriKind.Relative));
}
public ImageSource ImageSource { get; set; }
}
在视图中:
<Image Source="{Binding Path=ImageSource}"></Image>
作为对评论的回答,这也适用于列表框。
视图:
<ListBox ItemsSource="{Binding Path=MyImages}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Path=ImageSource}"/>
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
ViewModel:
public class MainWindowViewModel
{
public void LoadImages()
{
var d = new DirectoryInfo("assets/images");
var images = d.GetFiles();
MyImages = images.Select(x => new MyImageModel(x.Name, new BitmapImage(new Uri(x.FullName))));
}
public IEnumerable<MyImageModel> MyImages { get; set; }
}
MyImageModel
public class MyImageModel
{
public MyImageModel(string name, ImageSource imageSource)
{
Name = name;
ImageSource = imageSource;
}
public string Name { get; set; }
public ImageSource ImageSource { get; set; }
}