记一次WPF Image不显示图片问题

近日做项目时需要用到简单的WPF打印功能,需要打印的页面上有一个Image控件,调试代码的时候可以正常显示图片,但是我离开了调试,直接运行程序,Image中的图片一直显示不出来,网上搜索了很多相关问题,也向chatGPT问了很久都没有办法定位到问题,最后阴差阳错的给我发现了端倪。

框架是.NET6

先上代码:

1.我建了一个WPF类库,里面有一个WPF窗体:MainWindow.xaml

前端代码:

<Window x:Class="PrintWpf.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" SizeToContent="WidthAndHeight" Height="700" Width="794" Loaded="Window_Loaded">
    <Grid>
        <Canvas x:Name="printArea" Height="600" Width="794">
            <Image x:Name="IDCardPhoto" Width="204" Height="321" Margin="458,0,0,0"/>
        </Canvas>
    </Grid>
</Window>

后端代码:

using ...略

namespace PrintWpf
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private string imagePath = string.Empty;
        private string returnStr = string.Empty;

        public MainWindow(string path)
        {
            InitializeComponent();

            imagePath = path;
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            WinPosition();

            ConvertFilePathToBitmapImage();

            PrintDialog printDialog = new PrintDialog();
            if (printDialog.ShowDialog() == true)
            {
                printDialog.PrintVisual(printArea, "Print Window");
                returnStr = "complete";

                this.Close();
            }
            else
            {
                returnStr = "cancel";

                this.Close();
            }
        }

        /// <summary>
        /// 修改窗体初始显示位置
        /// </summary>
        private void WinPosition()
        {
            double ScreenWidth = System.Windows.SystemParameters.PrimaryScreenWidth;//WPF
            this.Top = this.ActualWidth / 5;
            this.Left = ScreenWidth - this.ActualWidth * 1.3;
        }

        /// <summary>
        /// windows文件绝对路径转化为WPF中Image控件的source属性
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public void ConvertFilePathToBitmapImage()
        {
            BitmapImage bitmapImage = new BitmapImage();
            bitmapImage.BeginInit();
            bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
            bitmapImage.StreamSource = new MemoryStream(File.ReadAllBytes(imagePath));
            bitmapImage.EndInit();
            bitmapImage.Freeze();
            IDCardPhoto.Source = bitmapImage;

        }

        public string ShowDia()
        {
            this.ShowDialog();
            return returnStr;
        }
    }
}

2.我建了一个winform项目,在里面调用上述的WPF窗体

string source = "图片来源(绝对路径)";
MainWindow mainWindow = new MainWindow(source);
string str  = mainWindow.ShowDia();
if (str == "complete")
{
    MessageBox.Show("启动打印");
}
else
{
    MessageBox.Show("不启动打印");
}

以上代码在我调试的时候,能正常显示出图片内容并打印无误,但是当我直接运行Debug里的程序时,图片就无法显示了,后来发现是我写的有问题,PrintDialog的调用放在了Window_Loaded里面导致图片还没完成加载就占用了窗体资源,导致无法显示图片。

于是我对上述代码做了一些修改,把PrintDialog的调用移出来

前端代码:(添加了一个打印按钮)

<Window x:Class="PrintWpf.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" SizeToContent="WidthAndHeight" Height="700" Width="794" Loaded="Window_Loaded">
    <Grid>

        <Button Content="打印" Canvas.Left="9" HorizontalAlignment="Left" VerticalAlignment="Top" Height="39" Width="92" Click="Button_Click"/>
        <Canvas x:Name="printArea" Height="600" Width="794">

            <Image x:Name="IDCardPhoto" Width="204" Height="321" Margin="458,0,0,0"/>
        </Canvas>
    </Grid>
</Window>

后端代码:(把PrintDialog的调用放到按钮事件中)

using ...略

namespace PrintWpf
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private string imagePath = string.Empty;
        private string returnStr = string.Empty;

        public MainWindow(string path)
        {
            InitializeComponent();

            imagePath = path;
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            WinPosition();

            ConvertFilePathToBitmapImage();
        }

        /// <summary>
        /// 修改窗体初始显示位置
        /// </summary>
        private void WinPosition()
        {
            double ScreenWidth = System.Windows.SystemParameters.PrimaryScreenWidth;//WPF
            this.Top = this.ActualWidth / 5;
            this.Left = ScreenWidth - this.ActualWidth * 1.3;
        }

        /// <summary>
        /// windows文件绝对路径转化为WPF中Image控件的source属性
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public void ConvertFilePathToBitmapImage()
        {
            BitmapImage bitmapImage = new BitmapImage();
            bitmapImage.BeginInit();
            bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
            bitmapImage.StreamSource = new MemoryStream(File.ReadAllBytes(imagePath));
            bitmapImage.EndInit();
            bitmapImage.Freeze();
            IDCardPhoto.Source = bitmapImage;

        }

        public string ShowDia()
        {
            this.ShowDialog();
            return returnStr;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            PrintDialog printDialog = new PrintDialog();
            if (printDialog.ShowDialog() == true)
            {
                printDialog.PrintVisual(printArea, "Print Window");
                returnStr = "complete";

                this.Close();
            }
            else
            {
                returnStr = "cancel";

                this.Close();
            }
        }
    }
}

这下图片加载跟打印分成了两部分,互不冲突,能正常显示图片和实现打印了。

这两天还搜到一些其他关于WPF Image控件不显示图片的问题回答,

有的说路径不对的,

有的说要把图片引入到项目中,并右键属性设置为资源的,这里就不展开说了,因为我的图片不是固定资源,是实时读取别的地方的文件。

ok,希望能帮到你。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值