C# WPF Image控件的綁定方法
在我們平時的開發中會經常用到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。
以上就是C# WPF Image控件的綁定方法的詳細內容,更多關於C# WPF Image控件的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- c# WPF中如何自定義MarkupExtension
- c# WPF實現Windows資源管理器(附源碼)
- WPF實現環(圓)形菜單的示例代碼
- C# WPF 自定義按鈕的方法
- C# WPF後臺動態添加控件實戰教程