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

如何在C#WPF应用程序中切换图像?,c#,wpf,image,xaml,C#,Wpf,Image,Xaml,我正在尝试制作一个应用程序,在硬币正面和反面的图像之间切换。但是,每次我按下“heads”按钮或“tails”按钮时,都会发生错误。如何修复代码以使映像成功切换 XAML: C#: 使用系统; 使用System.Collections.Generic; 使用System.Linq; 使用系统、媒体; 使用系统文本; 使用System.Threading.Tasks; 使用System.Windows; 使用System.Windows.Controls; 使用System.Windows.D

我正在尝试制作一个应用程序,在硬币正面和反面的图像之间切换。但是,每次我按下“heads”按钮或“tails”按钮时,都会发生错误。如何修复代码以使映像成功切换

XAML:


C#:

使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统、媒体;
使用系统文本;
使用System.Threading.Tasks;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
使用System.Windows.Documents;
使用System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Media.Imaging;
使用System.Windows.Navigation;
使用System.Windows.Shapes;
名称空间标题栏
{
/// 
///MainWindow.xaml的交互逻辑
/// 
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
}
已加载私有无效图像(对象发送器,路由目标e)
{
}
私有无效尾框按钮(对象发送器,路由目标e)
{
//创建第二个位图图像(尾部)
BitmapImage c=新的BitmapImage();
c、 BeginInit();
c、 UriSource=newURI(@“c:\Users\Raymond\Documents\visualstudio 2015\Projects\headortails\tails.jpg”);
c、 EndInit();
var image=发送方作为映像;
image.Source=c;
}
专用无效标题按钮\单击(对象发送者,路由目标e)
{
//创建新位图图像(头部)
BitmapImage b=新的BitmapImage();
b、 BeginInit();
b、 UriSource=newURI(@“C:\Users\Raymond\Documents\visualstudio 2015\Projects\headortails\heads.jpg”);
b、 EndInit();
var image=发送方作为映像;
image.Source=b;
}
私有无效退出按钮单击(对象发送者,路由目标)
{
这个。关闭();
}
}
}

您不能使用
sender
参数,因为这是按钮,而不是图像控件

改用
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"));
}

除此之外,您应该将这两个图像文件添加到VisualStudio项目中,将它们的
构建操作
设置为
资源
,并通过。这样,您就不必处理绝对文件路径:

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"));
}

然后还可以将位图图像添加为XAML资源:

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

克莱门斯是绝对正确的,他的第二种选择是非常优越的,因为它不会在每次翻转位图时重新加载位图。然而,如果我可以建议一个更好的替代方案(IMHO),而不是每次更改
coinImage
源代码,您可能希望有两个
图像
,例如,
CoinheadImage
coinTailsImage
,并在这些
单击
处理程序中翻转它们各自的
可见性
属性。将两个
图像
包装在各自的公共
网格中
,以便它们在视觉树中重叠。我不是100%确定,但我相信更改
图像的
可见性
比设置
源属性
在速度上更有效,而且无论哪种方式,这将是更好的体系结构,因为您可以使用适当的转换器将
可见性
属性直接绑定到代码隐藏或视图模型中假设的
IsHeads
属性


此外,任何时候使用
as
语法时,通常都应该检查结果是否为
null
。与简单类型转换不同,如果在使用
as
时对象无法转换为所需类型,则不会出现异常。如果您检查了
null
,您会在那里发现错误。

您能更新您的问题以指出您遇到了什么错误吗?请注意,不要在元素布局中使用边距。相反,在网格中定义行和列,并使用嵌套的布局控件,例如网格中带有按钮的StackPanel。默认情况下,从URI加载的BitMapImage会缓存,因此不会重新加载。即使从磁盘路径加载,这是真的吗?不知道。不确定,但是应该缓存从包URI加载。除此之外,在我看来,只有一个可见的两个图像控件是一个糟糕的方法。性能在这里并不重要。拥有一个视图模型当然值得一提,但是Image.Source属性应该绑定到一个ImageSource属性,并通过命令进行更改。对于这样一个简单的问题,这是相当多的代码。
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"));
}
<Window ...>
    <Window.Resources>
        <BitmapImage x:Key="heads" UriSource="heads.png"/>
        <BitmapImage x:Key="tails" UriSource="tails.png"/>
    </Window.Resources>
    ...
</Window>
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"];
}