简体   繁体   English

如何在 C# WPF 应用程序中切换图像?

[英]How to switch images in a C# WPF application?

I am trying to make an application that switches between an image of the heads sign of a coin and the tails side of a coin.我正在尝试制作一个在硬币正面标志图像和硬币背面之间切换的应用程序。 However, every time I press either the "heads" button or the "tails" button, an error occurs.但是,每次我按下“heads”按钮或“tails”按钮时,都会发生错误。 How can I fix my code so that the image successfully switches?如何修复我的代码以便图像成功切换?

XAML: XAML:

<Window x:Class="HeadsOrTails.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:HeadsOrTails"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Image 
        x:Name="coinImage"
        HorizontalAlignment="Center"
        Height="100"
        Margin="43,10,374,209"
        VerticalAlignment="Center"
        Width="100"
        Loaded="Image_Loaded"/>
    <Button x:Name="tailsButton" Content="Show Tails" HorizontalAlignment="Center" Height="40" Margin="190,214,197,65" VerticalAlignment="Center" Width="130" Click="tailsButton_Click"/>
    <Button x:Name="headsButton" Content="Show Heads" HorizontalAlignment="Center" Height="40" Margin="43,214,344,65" VerticalAlignment="Center" Width="130" Click="headsButton_Click"/>
    <Button x:Name="exitButton" Content="Exit" HorizontalAlignment="Center" Height="40" Margin="339,214,48,65" VerticalAlignment="Center" Width="130" Click="exitButton_Click"/>

</Grid>
</Window>

C#: C#:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Media;
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 HeadsOrTails
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Image_Loaded(object sender, RoutedEventArgs e)
    {

    }

    private void tailsButton_Click(object sender, RoutedEventArgs e)
    {
        //create a second bitmap image (tails)
        BitmapImage c = new BitmapImage();
        c.BeginInit();
        c.UriSource = new Uri(@"C:\Users\Raymond\Documents\Visual Studio 2015\Projects\HeadsOrTails\tails.jpg");
        c.EndInit();

        var image = sender as Image;
        image.Source = c;
    }

    private void headsButton_Click(object sender, RoutedEventArgs e)
    {
        //create the new bitmap image (heads)
        BitmapImage b = new BitmapImage();
        b.BeginInit();
        b.UriSource = new Uri(@"C:\Users\Raymond\Documents\Visual Studio 2015\Projects\HeadsOrTails\heads.jpg");
        b.EndInit();

        var image = sender as Image;
        image.Source = b;
    }

    private void exitButton_Click(object sender, RoutedEventArgs e)
    {
        this.Close();
    }
}
}

You can't use the sender argument, because that's the Button, not the Image control.您不能使用sender参数,因为那是 Button,而不是 Image 控件。

Use the coinImage member instead:改用coinImage成员:

private void headsButton_Click(object sender, RoutedEventArgs e)
{
    coinImage.Source = new BitmapImage(new Uri(@"C:\Users\Raymond Karrenbauer\Documents\Visual Studio 2015\Projects\HeadsOrTails\heads.jpg"));
}

private void tailsButton_Click(object sender, RoutedEventArgs e)
{
    coinImage.Source = new BitmapImage(new Uri(@"C:\Users\Raymond Karrenbauer\Documents\Visual Studio 2015\Projects\HeadsOrTails\tails.jpg"));
}

Besides that, you should add both image files to your Visual Studio project, set their Build Action to Resource and access them by a Resource File Pack URI .除此之外,您应该将两个图像文件添加到您的 Visual Studio 项目中,将它们的Build Action设置为Resource并通过Resource File Pack URI访问它们。 This way you wouldn't have to deal with absolute file paths:这样您就不必处理绝对文件路径:

private void headsButton_Click(object sender, RoutedEventArgs e)
{
    coinImage.Source = new BitmapImage(new Uri("pack://application:,,,/heads.jpg"));
}

private void tailsButton_Click(object sender, RoutedEventArgs e)
{
    coinImage.Source = new BitmapImage(new Uri("pack://application:,,,/tails.jpg"));
}

You may then also add the BitmapImages as XAML Resources:然后,您还可以将 BitmapImages 添加为 XAML 资源:

<Window ...>
    <Window.Resources>
        <BitmapImage x:Key="heads" UriSource="heads.png"/>
        <BitmapImage x:Key="tails" UriSource="tails.png"/>
    </Window.Resources>
    ...
</Window>

And use them like this:并像这样使用它们:

private void headsButton_Click(object sender, RoutedEventArgs e)
{
    coinImage.Source = (ImageSource)Resources["heads"];
}

private void tailsButton_Click(object sender, RoutedEventArgs e)
{
    coinImage.Source = (ImageSource)Resources["tails"];
}

Clemens is absolutely right, and his second alternative is far superior because it doesn't re-load the bitmaps each time you flip them. Clemens 是绝对正确的,他的第二个选择要好得多,因为它不会在您每次翻转位图时重新加载它们。 However if I may suggest an even better alternative (IMHO) to what you're doing, instead of changing the Source of the coinImage each time, you might instead want to have two Image s, for example, coinHeadsImage and coinTailsImage , and flip their respective Visibility properties in those Click handlers.但是,如果我可以为您正在做的事情提出更好的替代方案(恕我直言),而不是每次更改coinImageSource ,您可能想要拥有两个Image ,例如, coinHeadsImagecoinTailsImage ,并翻转它们这些Click处理程序中的相应Visibility属性。 Wrap both Image s in their own common Grid so that they are overlapping in the visual tree.将两个Image包裹在它们自己的公共Grid以便它们在可视化树中重叠。 I'm not 100% certain, but I believe changing the Visibility of the Images would be more efficient speed-wise than setting the Source property, and either way, it would be better architecture because you could bind the Visibility properties directly to a hypothetical IsHeads property in your code-behind or view model, using appropriate converters of course.我不是 100% 确定,但我相信更改ImagesVisibility比设置Source属性在速度上更有效,无论哪种方式,它都会是更好的架构,因为您可以将Visibility属性直接绑定到假设代码隐藏或视图模型中的IsHeads属性,当然使用适当的转换器。

Also, any time you use the as syntax, you generally should check the result for null .此外,任何时候使用as语法时,通常都应该检查结果是否为null Unlike a simple type cast, you won't get an exception if the object cannot covert to the desired type when you use as .与简单类型转换不同,如果在使用as时对象无法转换为所需类型,则不会出现异常。 Had you checked for null you would have caught your error there.如果你检查了null你就会在那里发现你的错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM