Вы просмотрели отображение базы данных и пакеты доступа в http://hackage.haskell.org/packages/archive/pkg-list.html#cat:Database
, я не использовал их, так не может рекомендовать никакой конкретный. Я также не знаю, какие базы данных Вы - планирование использования.
WPF работает с ImageSource
s, а не с System.Drawing
классы. Вам нужно будет выполнить привязку к ImageSource
. Вы можете использовать конвертер для преобразования вашего Bitmap
в ImageSource
, или вы можете отказаться от ресурсов и сделать что-то по-другому.
Here's how I made a ViewModel for a menu item: AbstractMenuItem. Pay particular attention to the Icon region:
#region " Icon "
/// <summary>
/// Optional icon that can be displayed in the menu item.
/// </summary>
public object Icon
{
get
{
if (IconFull != null)
{
System.Windows.Controls.Image img = new System.Windows.Controls.Image();
if (EnableCondition.Condition)
{
img.Source = IconFull;
}
else
{
img.Source = IconGray;
}
return img;
}
else
{
return null;
}
}
}
private BitmapSource IconFull
{
get
{
return m_IconFull;
}
set
{
if (m_IconFull != value)
{
m_IconFull = value;
if (m_IconFull != null)
{
IconGray = ConvertFullToGray(m_IconFull);
}
else
{
IconGray = null;
}
NotifyPropertyChanged(m_IconArgs);
}
}
}
private BitmapSource m_IconFull = null;
static readonly PropertyChangedEventArgs m_IconArgs =
NotifyPropertyChangedHelper.CreateArgs<AbstractMenuItem>(o => o.Icon);
private BitmapSource IconGray { get; set; }
private BitmapSource ConvertFullToGray(BitmapSource full)
{
FormatConvertedBitmap gray = new FormatConvertedBitmap();
gray.BeginInit();
gray.Source = full;
gray.DestinationFormat = PixelFormats.Gray32Float;
gray.EndInit();
return gray;
}
/// <summary>
/// This is a helper function so you can assign the Icon directly
/// from a Bitmap, such as one from a resources file.
/// </summary>
/// <param name="value"></param>
protected void SetIconFromBitmap(System.Drawing.Bitmap value)
{
BitmapSource b = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
value.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
IconFull = b;
}
#endregion
You just derive from this class and in the constructor you call SetIconFromBitmap and pass in a picture from your resx file.
Here's how I bound to those IMenuItems in the Workbench Window:
<Menu DockPanel.Dock="Top" ItemsSource="{Binding Path=(local:Workbench.MainMenu)}">
<Menu.ItemContainerStyle>
<Style>
<Setter Property="MenuItem.Header" Value="{Binding Path=(contracts:IMenuItem.Header)}"/>
<Setter Property="MenuItem.ItemsSource" Value="{Binding Path=(contracts:IMenuItem.Items)}"/>
<Setter Property="MenuItem.Icon" Value="{Binding Path=(contracts:IMenuItem.Icon)}"/>
<Setter Property="MenuItem.IsCheckable" Value="{Binding Path=(contracts:IMenuItem.IsCheckable)}"/>
<Setter Property="MenuItem.IsChecked" Value="{Binding Path=(contracts:IMenuItem.IsChecked)}"/>
<Setter Property="MenuItem.Command" Value="{Binding}"/>
<Setter Property="MenuItem.Visibility" Value="{Binding Path=(contracts:IControl.Visible),
Converter={StaticResource BooleanToVisibilityConverter}}"/>
<Setter Property="MenuItem.ToolTip" Value="{Binding Path=(contracts:IControl.ToolTip)}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=(contracts:IMenuItem.IsSeparator)}" Value="true">
<Setter Property="MenuItem.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Separator Style="{DynamicResource {x:Static MenuItem.SeparatorStyleKey}}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Menu.ItemContainerStyle>
</Menu>
Кент (конечно) знает правильный ответ. Но я решил пойти дальше и опубликовать код конвертера, который преобразует System.Drawing.Bitmap (Windows Forms) в System.Windows.Windows.Media.BitmapSource (WPF) ... так как это обычная проблема / вопрос.
Для этого нужно сделать три шага:
Вот как можно использовать конвертер изображений в привязке :
<Setter
Property="MenuItem.Icon"
Value="{Binding Path=Icon, Converter={StaticResource imageConverter}}"
/>
А вот код конвертера (поместите его в файл с именем ImageConverter.cs) и добавьте в свой project:
[ValueConversion(typeof(Image), typeof(string))]
public class ImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
BitmapSource bitmapSource;
IntPtr bitmap = ((Bitmap)value).GetHbitmap();
try
{
bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(bitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
}
finally
{
DeleteObject(bitmap);
}
return bitmapSource;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
[DllImport("gdi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
static extern int DeleteObject(IntPtr o);
}
Вот как вы объявляете его в разделе ресурсов (обратите внимание на локальное пространство имен, которое вам нужно будет добавить):
<Window
x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication2"
>
<Window.Resources>
<local:ImageConverter x:Key="imageConverter"/>
</Window.Resources>
<!-- some xaml snipped for clarity -->
</Window>
И все!
Обновление
Проведя быстрый поиск похожих вопросов, я заметил, что Ларс Труидженс указал здесь , что в предыдущей реализации преобразователя произошла утечка. Я обновил приведенный выше код конвертера ... чтобы он не протекал.
Дополнительные сведения о причине утечки см. В разделе примечаний по этой ссылке MSDN .