如何将图像绑定到DataGrid中的UserControl(带图像的按钮) [英] How do I bind an image to an UserControl (button with image) in a DataGrid
问题描述
我正在开发一个小项目,我需要一个DataGrid,其中一列包含一个imageButton作为UserControl。
我正在努力的是如何将图像源绑定到我的UserControl中的图像。
我将所有内容都删除,只剩下这个功能了,我猜我我只是错过了一些小东西才能让它运行。
任何帮助都是最受欢迎的。
我的UserControl:
I'm working on a small project, where I need a DataGrid where a column contains an imageButton as a UserControl.
What I'm struggling with is how to bind the image source to the image in my UserControl.
I stripped everything down to only have this function left and I guess I'm just missing something small to get it run.
Any help would be most welcome.
My UserControl:
<UserControl x:Class="OpenPointList.UserControls.DataGridButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid x:Name="LayoutRoot">
<Button Click="DataGridButton_Click">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="Border"
BorderThickness="0"
removed="LightBlue">
<Border.Child>
<StackPanel Orientation="Horizontal">
<Image Name="ButtonImage"
Source="{Binding Image}"/>
<TextBlock Name="ButtonText"
Text="{Binding Text}"/>
</StackPanel>
</Border.Child>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimationUsingKeyFrames
Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Background).(Color)">
<EasingColorKeyFrame KeyTime="0"
Value="Red"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed"/>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
</Grid>
</UserControl>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace OpenPointList.UserControls
{
/// <summary>
/// Interaction logic for DataGridButton.xaml
/// </summary>
public partial class DataGridButton : UserControl
{
public DataGridButton()
{
InitializeComponent();
//this.DataContext = this;
}
public ImageSource Image
{
get { return (ImageSource)GetValue(ImageProperty); }
set { SetValue(ImageProperty, value); }
}
public static readonly DependencyProperty ImageProperty =
DependencyProperty.Register("Image", typeof(ImageSourceConverter), typeof(DataGridButton), new UIPropertyMetadata(null));
public string Text
{
get { return (String)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(DataGridButton), new UIPropertyMetadata(""));
public event RoutedEventHandler Click;
private void DataGridButton_Click(object sender, RoutedEventArgs e)
{
if (Click != null)
{
Click(this, e);
}
}
}
}
我的数据模型:
My Model for the data:
using System;
using System.ComponentModel;
using System.Windows.Media;
namespace OpenPointList.Model
{
public class OplItem : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
#region Fields
private int _number;
private string _statusImage;
#endregion // Fields
#region Properties
public int Number
{
get { return _number; }
set
{
_number = value;
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Number"));
}
}
public string StatusImage
{
get { return _statusImage; }
set
{
_statusImage = value;
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("StatusImage"));
}
}
#endregion // Properties
}
}
我的ViewModel:
My ViewModel:
using System;
using System.Collections.ObjectModel;
using System.Windows.Input;
using OpenPointList.Model;
namespace OpenPointList.ViewModel
{
public class MainWindowViewModel
{
#region Fields
ObservableCollection<OplItem> _opl;
private string _image1 = "pack://application:,,,/Image1_32x32.png";
private string _image2 = "pack://application:,,,/Image2_32x32.png";
private ICommand _addOplItemCommand;
#endregion // Fields
#region Constructor
public MainWindowViewModel()
{
_opl = new ObservableCollection<OplItem>();
_opl.Add(new OplItem() { Number = 1, StatusImage = _image1 });
_opl.Add(new OplItem() { Number = 2, StatusImage = _image1 });
_opl.Add(new OplItem() { Number = 3, StatusImage = _image1 });
AddOplItemCommand = new RelayCommand(param => this.AddOplItem());
}
#endregion // Constructor
#region Properties
public ObservableCollection<OplItem> Opl
{
get { return _opl; }
set { _opl = value; }
}
#endregion // Properties
#region AddOplItemCommand
/// <summary>
/// Returns the command that, when invoked, will add a new item to the OPL.
/// </summary>
public ICommand AddOplItemCommand
{
get { return _addOplItemCommand; }
set { _addOplItemCommand = value; }
}
#endregion // AddOplItemCommand
#region AddOplItem
/// <summary>
/// Add a new item to the OPL.
/// </summary>
private void AddOplItem()
{
_opl.Add(new OplItem() { Number = _opl.Count + 1, StatusImage = _image1 });
_opl[_opl.Count - 2].StatusImage = _image2;
}
#endregion // AddOplItem
}
}
And my View:
And my View:
<Window x:Class="OpenPointList.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:userControls="clr-namespace:OpenPointList.UserControls">
<Grid x:Name="MainGrid">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<DataGrid Name="OplDataGrid"
AutoGenerateColumns="False" CanUserAddRows="False"
ItemsSource="{Binding Opl}">
<DataGrid.Columns>
<DataGridTextColumn Header="No." Width="30"
Binding="{Binding Path=Number,
UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTemplateColumn Header="UserControl without Binding">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<userControls:DataGridButton
Image="pack://application:,,,/Image1_32x32.png"
Text="Hello"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="UserControl with Binding">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<userControls:DataGridButton
Image="{Binding Path=StatusImage,
UpdateSourceTrigger=PropertyChanged}"
Text="{Binding Path=Number,
UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Image">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding Path=StatusImage,
UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<Button Content="Add Item" Grid.Row="1" Width="50"
Command="{Binding Path=AddOplItemCommand}"/>
</Grid>
</Window>
using System.Windows;
namespace OpenPointList
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
And for completeness also the remaining files:
And for completeness also the remaining files:
<Application x:Class="OpenPointList.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!--StartupUri="MainWindow.xaml">-->
<Application.Resources>
</Application.Resources>
</Application>
using System;
using System.Windows;
using OpenPointList.ViewModel;
namespace OpenPointList
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
static App() { }
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
OpenPointList.MainWindow window = new MainWindow();
// Create the ViewModel to which the main window binds.
MainWindowViewModel mainWindowViewModel = new MainWindowViewModel();
window.DataContext = mainWindowViewModel;
window.Show();
}
}
}
The RelayCommand class is from the this MSDN Article: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx:
The RelayCommand class is from the this MSDN Article: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx:
using System;
using System.Diagnostics;
using System.Windows.Input;
namespace OpenPointList
{
/// <summary>
/// A command whose sole purpose is to relay its functionality to other
/// objects by invoking delegates. The default return value for the CanExecute
/// method is 'true'.
/// </summary>
public class RelayCommand : ICommand
{
#region Fields
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
#endregion // Fields
#region Constructors
/// <summary>
/// Creates a new command that can always execute.
/// </summary>
/// <param name="execute">The execution logic.</param>
public RelayCommand(Action<object> execute) : this(execute, null)
{
}
/// <summary>
/// Creates a new command.
/// </summary>
/// <param name="execute">The execution logic.</param>
/// <param name="canExecute">The execution status logic.</param>
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
#endregion // Constructors
#region ICommand Members
[DebuggerStepThrough]
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
_execute(parameter);
}
#endregion // ICommand Members
}
}
推荐答案
Give the last entry in this blog a try.[^]
Give the last entry in this blog a try.[^]
这篇关于如何将图像绑定到DataGrid中的UserControl(带图像的按钮)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!