C# WPF Image控件的绑定方法

作者:Hello——寻梦者! 时间:2023-09-03 06:41:42 

     在我们平时的开发中会经常用到Image控件,通过设置Image控件的Source属性,我们可以加载图片,设置Image的source属性时可以使用相对路径也可以使用绝对路径,一般情况下建议使用绝对路径,类似于下面的形式Source="/Demo;Component/Images/Test.jpg"其中Demo表示工程的名称,后面表示具体哪个文件夹下面的哪个图片资源,在程序中,我们甚至可以为Image控件设置X:Name属性,在后台代码中动态去改变Image的Source,但我个人认为这种方式不太适合最大量的图片切换,而且增加了View层和代码之间的耦合性,不是和复合MVVM的核心设计思想,所以今天就总结一下Image的动态绑定的形式。

    要绑定,肯定是绑定到Image控件的Source属性上面,我们首先要搞清楚Source的类型是什么,public ImageSource Source { get; set; }也就是ImageSource类型,当然在我们绑定的时候用的最多的就是BitmapImage这个位图图像啦,我们首先来看看BitmapImage的继承关系:BitmapImage:BitmapSource:ImageSource,最终也是一种ImageSource类型。当然在我们的Model层中我们也可以直接定义一个BitmapImage的属性,然后将这个属性直接绑定到Image的Source上面,当然这篇文章我们定义了一个ImgSource的String类型,所以必须要定义一个转换器Converter,这里分别贴出相应地代码。

首先是View层,比较简单:


   <Grid Grid.Row="1">
     <Image Source="{Binding Path=LTEModel.ImgSource,Converter={StaticResource MyImageConverter}}" Stretch="Fill">
     </Image>
   </Grid>

然后我们再来看看Model层也很简单。


public class LTEModel : BaseModel
 {
   private string _imageSource = null;
   public string ImgSource
   {
     get
     {
       return _imageSource;
     }
     set
     {
       if (value != _imageSource)
       {
         _imageSource = value;
         FirePropertyChanged("ImgSource");
       }
     }
   }
 }

然后就是重要的转换器:


public class StringToImageSourceConverter:IValueConverter
 {
   #region Converter

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
   {
     string path = (string)value;
     if (!string.IsNullOrEmpty(path))
     {
       return new BitmapImage(new Uri(path, UriKind.Absolute));
     }
     else
     {
       return null;
     }
   }

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
   {
     return null;
   }
   #endregion
 }

然后就是重要的转换器:


public class StringToImageSourceConverter:IValueConverter
 {
   #region Converter

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
   {
     string path = (string)value;
     if (!string.IsNullOrEmpty(path))
     {
       return new BitmapImage(new Uri(path, UriKind.Absolute));
     }
     else
     {
       return null;
     }
   }

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
   {
     return null;
   }
   #endregion
 }

转换器返回的是Object类型,实际返回的是一个BitmapImage对象。所以我们在写程序绑定的时候一定要弄清绑定的目标和对象之间的关系,这个是非常重要的。

下面就是在ViewModel层中来添加绑定,并更新数据源,这里使用的是一个定时器来定时更新数据源:


public class LTEViewModel : NotifyObject
 {
   private DispatcherTimer myDispatcher = null;
   private Random random = new Random();
   public LTEViewModel()
   {
     GetImageSource();
     InitTimer();
   }

private LTEModel _lteModel = null;
   public LTEModel LTEModel
   {
     get
     {
       if (_lteModel == null)
       {
         _lteModel = new LTEModel();
       }
       return _lteModel;
     }
     set
     {
       if (value != _lteModel)
       {
         _lteModel = value;
         FirePropertyChanged("LTEModel");
       }
     }
   }

private BaseModel _baseModel = null;
   public BaseModel BaseModelInstance
   {
     get
     {
       if (_baseModel == null)
       {
         _baseModel = new BaseModel()
         {
           Title = "分地区LTE分布",
           Time = DateTime.Now.ToString()
         };
       }
       return _baseModel;
     }
     set
     {
       if (value != _baseModel)
       {
         _baseModel = value;
         FirePropertyChanged("BaseModelInstance");
       }
     }
   }

private List<string> imgList = new List<string>();
   private void GetImageSource()
   {
     //通过程序集来读取相应的资源的路径
     string assemblyLocation = this.GetType().Assembly.Location;
     string assLocation = assemblyLocation.Substring(0, assemblyLocation.LastIndexOf("\\"));
     string[] img_files = Directory.GetFiles(string.Format("{0}\\Images", assLocation), "*.JPG");
     foreach (string img_path in img_files)
     {
       imgList.Add(img_path);
     }
   }

private void InitTimer()
   {
     myDispatcher = new DispatcherTimer();
     myDispatcher.Tick += new EventHandler(Timer_Tick);
     myDispatcher.Interval = TimeSpan.FromMilliseconds(1000);
     myDispatcher.Start();
   }

private void Timer_Tick(object sender, EventArgs e)
   {
     int imageIndex = 0;
     if (imgList.Count > 0 && LTEModel != null)
     {
       imageIndex = random.Next(0, imgList.Count);
       LTEModel.ImgSource = imgList[imageIndex];
     }
     if (_baseModel != null)
     {
       _baseModel.Time = DateTime.Now.ToString();
     }
   }
 }

然后就是实例化一个ViewModel对象绑定到前台中,这个思路其实是相当明确的。

      其实在我们的很多时候,我们并不知道我们需要绑定什么图片,或者说根据数据类型来绑定图片,这个在定义数据模板的时候经常使用到,下面就介绍一下,根据类型来绑定相应的图片。然后通过定义 


public enum DeviceType
{
SheXiangJi,
KaKou,
DianZiJingCha,
MingJin
}

这种类型,通过不同的类型来绑定到不同的图片,这个也是一个非常重要的应用,我们一定要注意使用的方法,这里只是简单介绍一下。   


<ItemsControl ItemsSource="{Binding DeviceList,RelativeSource={RelativeSource TemplatedParent}}" Grid.Row="2">
             <ItemsControl.Template>
               <ControlTemplate TargetType="ItemsControl">
                 <UniformGrid Columns="3" Rows="7" IsItemsHost="True"></UniformGrid>
               </ControlTemplate>
             </ItemsControl.Template>
             <ItemsControl.ItemTemplate>
               <DataTemplate>
                 <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="20 0 0 0" VerticalAlignment="Center" SnapsToDevicePixels="True">
                   <Image x:Name="icon1" Width="48" Height="48" RenderOptions.BitmapScalingMode="NearestNeighbor" VerticalAlignment="Center"></Image>
                   <TextBlock Margin="10 0 0 0" Foreground="#fff" ToolTip="{Binding Name}" FontSize="40" Text="{Binding Name}" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock>
                 </StackPanel>
                 <DataTemplate.Triggers>
                   <DataTrigger Binding="{Binding Type}" Value="SheXiangJi">
                     <Setter Property="Source" Value="/IGisControls.JTJ.UIControls;component/images/camera.png" TargetName="icon1"></Setter>
                   </DataTrigger>
                   <DataTrigger Binding="{Binding Type}" Value="KaKou">
                     <Setter Property="Source" Value="/IGisControls.JTJ.UIControls;component/images/Bayonet.png" TargetName="icon1"></Setter>
                   </DataTrigger>
                   <DataTrigger Binding="{Binding Type}" Value="DianZiJingCha">
                     <Setter Property="Source" Value="/IGisControls.JTJ.UIControls;component/images/epolice.png" TargetName="icon1"></Setter>
                   </DataTrigger>
                   <DataTrigger Binding="{Binding Type}" Value="MingJin">
                     <Setter Property="Source" Value="/IGisControls.JTJ.UIControls;component/images/Police_A.png" TargetName="icon1"></Setter>
                   </DataTrigger>
                 </DataTemplate.Triggers>
               </DataTemplate>
             </ItemsControl.ItemTemplate>
           </ItemsControl>

    另外和Image很类似的就是 <ImageBrush ImageSource="/IGisControls.JTJ.UIControls;component/images/screenBG.jpg" Stretch="Fill"></ImageBrush>

用法也差不多,同样可以通过绑定的方式来添加图片,不过在使用的时候还是需要注意一下就是设置当前图片的生成操作为Resource。

来源:https://www.cnblogs.com/seekdream/p/5277237.html

标签:c#,wpf,Image控件
0
投稿

猜你喜欢

  • 详解SpringBoot获得Maven-pom中版本号和编译时间戳

    2022-11-27 19:45:27
  • 以Java代码为例讲解设计模式中的简单工厂模式

    2023-02-09 15:14:17
  • 29个要点帮你完成java代码优化

    2022-11-06 05:16:26
  • Android 游戏引擎libgdx 资源加载进度百分比显示案例分析

    2023-05-12 12:18:46
  • Android 圆角边框的实现方式汇总

    2023-03-20 04:27:46
  • Spring Boot2.0 @ConfigurationProperties使用详解

    2021-06-11 17:21:30
  • C++/java 继承类的多态详解及实例代码

    2022-11-28 10:22:06
  • Java深入了解数据结构之二叉搜索树增 插 删 创详解

    2023-02-14 08:08:00
  • Android基于SoftReference缓存图片的方法

    2023-07-13 00:53:21
  • Android开发中amera2 Preview使用详解

    2023-11-09 20:17:56
  • C# 添加、修改以及删除Excel迷你图表的实现方法

    2023-04-06 22:07:27
  • Java日常练习题,每天进步一点点(52)

    2023-03-31 11:23:46
  • 浅析Java中Apache BeanUtils和Spring BeanUtils的用法

    2021-07-10 21:29:15
  • SpringBoot集成POI实现Excel导入导出的示例详解

    2022-12-05 19:09:10
  • java 实现比较版本号功能

    2022-08-12 20:35:11
  • JAVA中的字符串常量池使用操作代码

    2021-11-24 02:00:57
  • SpringBoot 使用Prometheus采集自定义指标数据的方案

    2023-04-25 02:50:39
  • c语言中十六进制转二进制显示的实现方法

    2023-12-17 23:21:44
  • 详解Java回环屏障CyclicBarrier

    2022-08-30 15:02:09
  • Android深入浅出之Binder机制

    2021-07-06 01:47:21
  • asp之家 软件编程 m.aspxhome.com