WPF Tooltip Image in Datagrid Column - wpf

I need to have a datagrid column with some image, and for each cell I need to see, in the tooltip, the bigger image.
The datagrid is binded on a ObsevarbleCollection of MyOBjects, and MyImage and MyBigImage are poperties of MyObject.
With XAML here there is the working code:
<c1:C1DataGrid.Columns>
<c1:DataGridTemplateColumn>
<c1:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding MyImage}" >
<Image.ToolTip>
<ToolTip >
<StackPanel>
<Image Source="{Binding MyBigImage}" />
</StackPanel>
</ToolTip>
</Image.ToolTip>
</Image>
</DataTemplate>
</c1:DataGridTemplateColumn.CellTemplate>
</c1:DataGridTemplateColumn>
</c1:C1DataGrid.Columns>
But I need to move the code in the c# side.
So I've tried this code:
C1.WPF.DataGrid.DataGridTemplateColumn col1 = new
C1.WPF.DataGrid.DataGridTemplateColumn();
FrameworkElementFactory factoryImg = new
FrameworkElementFactory(typeof(Image));
Binding b1 = new Binding("MyImage");
b1.Mode = BindingMode.TwoWay;
factoryImg.SetValue(Image.SourceProperty, b1);
DataTemplate ttTemplate = new DataTemplate(typeof(StackPanel));
FrameworkElementFactory spFactory = new
FrameworkElementFactory(typeof(StackPanel));
spFactory.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);
FrameworkElementFactory imgHolder = new
FrameworkElementFactory(typeof(Image));
Binding b2 = new Binding("MyBigImage");
b2.Mode = BindingMode.TwoWay;
imgHolder.SetBinding(Image.SourceProperty, b2);
spFactory.AppendChild(imgHolder);
ttTemplate.VisualTree = spFactory;
ToolTip tt = new System.Windows.Controls.ToolTip();
tt.ContentTemplate = ttTemplate;
factoryImg.SetValue(TextBlock.ToolTipProperty, tt);
DataTemplate cellTemplate1 = new DataTemplate();
cellTemplate1.VisualTree = factoryImg;
col1.CellTemplate = cellTemplate1;
MyDataGrid.Columns.Add(col1);
cellTemplate1.Seal();
With this code the image in the cell appears correctly, but the tooltip on the image is an empty panel, no image is visualized.
If I create a new BitmapImage the tooltip works, so I think it is a binding problem.
What I'm doing wrong?

Ok solved, I've forgot to set the DataContext property:
imgHolder.SetValue(TextBlock.DataContextProperty, List);

Related

Binding to an attached property in code behind

How can I implement the following xaml binding in code behind?
<Canvas x:Name="_YAxis">
<Label Content="0.2" Canvas.Left="25" Canvas.Bottom="{Binding ElementName=_YAxis, Path=ActualHeight, Converter={StaticResource myPercentageOf}, ConverterParameter={StaticResource Constant_pt2} }" />
</Canvas>
Note, the converter simply multiplies the actual height of the Canvas by 0.2
I can sort out most kind of bindings, but this one has me stumped.
I can create the binding using
Label label = new Label() { label.Content = "0.2" };
Binding binding = new Binding("ActualHeight");
binding.Source = _YAxis;
// attach binding ???
_YAxis.Children.Add(label);
but how do I attach the binding to the Canvas.Left attached property?
Here you go:
Binding b = new Binding();
b.Path = new PropertyPath("ActualHeight");
b.Source = _YAxis;// OR b.ElementName = "_YAxis"
b.Converter = Resources["myPercentageOf"];
b.ConverterParameter = Resources["Constant_pt2"];
Label label = new Label() { label.Content = "0.2" };
_YAxis.Children.Add(label);
label.SetBinding(Canvas.BottomProperty, b); //Binding Canvas.Bottom to ActualHeight of _YAxis
Canvas.SetLeft(label, 25); //Setting Canvas.Left

Programmatically add Panorama Items

I am working on windows Phone 7.5 App and I want to display a list of images programmatically in panorama control.I have the xaml
<!--Panorama item three-->
<controls:PanoramaItem x:Name="DiaPanorama" Header="History" FontSize="20">
and the code part is -
PanoramaItem p = new PanoramaItem();
Image i = new Image();
i.Source = new BitmapImage(new Uri("/web.png", UriKind.Relative));
p.Margin = new Thickness(0, -10, 0, -2);
p.Content = i;
DiaPanorama.Items.Add(p);
but it's showing an error that Microsoft.Phone.Control.PanoramaItem does not contain defination for Items.
How can i solve this problem?Please help.
Is there any other approach for adding images programmatically in panorama?
According to your sample, you're trying to add a new PanoramaItem to an existing PanoramaItem. That won't work - you'd need to add the new PanoramaItem to the parent controls:Panorama object.
When adding multiple items to a PanoramaItem or PivotItem, you must add a containing element first such as a Grid, StackPanel or Canvas
In XAML
<controls:Panorama x:Name="Panorama" Title="Panorama Control">
<controls:PanoramaItem x:Name="Item1" Header="Item 1">
<StackPanel>
<TextBlock Text="Hello World" />
<Image Source="Background.png" />
</StackPanel>
</controls:PanoramaItem>
</controls:Panorama>
In C#
var item = new PanoramaItem();
var panel = new StackPanel();
var text = new TextBlock();
text.Text = "HelloWorld";
panel.Children.Add(text);
var image = new Image();
image.Source = new BitmapImage(new Uri("Background.png", UriKind.Relative));
panel.Children.Add(image);
item.Content = panel;
Panorama.Items.Add(item); // Add to existing panorama control

Stretching Toolbar in a toolbartray codebehind and xaml

I need the following xaml code snippet in cs (code behind file)
<ToolBarTray Width="450" IsLocked="True" >
<ToolBar Width="{Binding ActualWidth,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type ToolBarTray}}}">
<Button>B1</Button>
<Button>B2</Button>
</ToolBar>
</ToolBarTray>
If you really intend to use this code in the codebehind than the snippet below should be fine. However, it will not work if you want to create a DataTemplate from code. In that case you need to use FrameworkElementFactory derived types and not FrameoworkElement derived types.
public ToolBarTray CreatetoolBarTray()
{
var tbt = new ToolBarTray
{
Width = 450.0,
IsLocked = true
};
var tb = new ToolBar();
var b = new Binding
{
Path = new PropertyPath("ActualWidth"),
Source = new RelativeSource(RelativeSourceMode.FindAncestor, typeof (ToolBarTray), 1),
};
tb.SetBinding(WidthProperty, b);
tb.Items.Add(new Button() {Content = "b1"});
tb.Items.Add(new Button() {Content = "b2"});
tbt.ToolBars.Add(tb);
return tbt;
}

Using code behind only add button to dynamically generated WPF DataGrid column's header

I have a wpf datagrid that has it's columns generated dynamically in code and I need to insert small buttons in each column's header to the right of the text to implement custom (complex) filtering in a popup dialog.
I'm having trouble figuring out how to insert a button into a datagrid column header using only code behind.
This is the route I started going down (commented out bit) but it doesn't work:
private static DataGridTextColumn GetTextColumn(string ColumnName, string FormatString, bool AlignRight)
{
DataGridTextColumn c = new DataGridTextColumn();
c.Header = Test.Common.UIBizObjectCache.LocalizedText.GetLocalizedText(ColumnName);
c.Binding = new System.Windows.Data.Binding(ColumnName);
if (!string.IsNullOrWhiteSpace(FormatString))
c.Binding.StringFormat = FormatString;
if (AlignRight)
{
Style cellRightAlignedStyle = new Style(typeof(DataGridCell));
cellRightAlignedStyle.Setters.Add(new Setter(DataGridCell.HorizontalAlignmentProperty, HorizontalAlignment.Right));
c.CellStyle = cellRightAlignedStyle;
}
//var buttonTemplate = new FrameworkElementFactory(typeof(Button));
//buttonTemplate.Text = "X";
//buttonTemplate.AddHandler(
// Button.ClickEvent,
// new RoutedEventHandler((o, e) => HandleColumnHeaderButtonClick(o, e))
// );
//c.HeaderTemplate=new DataTemplate(){VisualTree = buttonTemplate};
return c;
}
I get an invalidoperationexception "'ContentPresenter' type must implement IAddChild to be used in FrameworkElementFactory AppendChild."
Clearly I'm doing it wrong. :) Any help would be greatly appreciated.
Do you need to use a template? If not use the normal Header property:
string colProperty = "Name";
DataGridTextColumn col = new DataGridTextColumn();
col.Binding = new Binding(colProperty);
var spHeader = new StackPanel() { Orientation = Orientation.Horizontal };
spHeader.Children.Add(new TextBlock(new Run(colProperty)));
var button = new Button();
button.Click += Button_Filter_Click;
button.Content = "Filter";
spHeader.Children.Add(button);
col.Header = spHeader;
dataGrid.Columns.Add(col);
For create a column header with an image button, you can do this in xaml :
<Window.Resources>
<BitmapImage x:Key="Img" UriSource="/Img/yourImage.png"/>
</Window.Resources>
<Datagrid Name="yourDatagrid">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button x:Name="Btn" Click="Btn_Click" >
<DockPanel>
<Image Source="{StaticResource ResourceKey=Img}" Height="16" Width="16"/>
</DockPanel>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</Datagrid>
Or you can autogenerate this in code behind like this :
Xaml :
<Window.Resources>
<BitmapImage x:Key="Img" UriSource="/Img/yourImage.png"/>
</Window.Resources>
C# :
Datagrid yourDatagrid = new Datagrid();
DataGridTemplateColumn colBtn = new DataGridTemplateColumn();
DataTemplate DttBtn = new DataTemplate();
FrameworkElementFactory btn = new FrameworkElementFactory(typeof(Button));
FrameworkElementFactory panel = new FrameworkElementFactory(typeof(DockPanel));
FrameworkElementFactory img = new FrameworkElementFactory(typeof(Image));
img.SetValue(Image.SourceProperty, (BitmapImage)FindResource("Img"));
img.SetValue(Image.HeightProperty, Convert.ToDouble(16));
img.SetValue(Image.WidthProperty, Convert.ToDouble(16));
panel.AppendChild(img);
btn.AppendChild(panel);
btn.AddHandler(Button.ClickEvent, new RoutedEventHandler(Btn_Click));
DttBtn.VisualTree = btn;
colBtn.CellTemplate = DttBtn;
yourDatagrid.Columns.Add(colBtn);

How do I show image in wpf datagrid column programmatically?

I want to add two columns in wpf datagrid one image & one text columns dynamically.
Xaml code :
<Grid><DataGrid AutoGenerateColumns="False" Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="grid" VerticalAlignment="Stretch" Width="Auto" ></DataGrid></Grid>
Code Behind:
DataGridTextColumn col = new DataGridTextColumn();
col.Header =Text1;
col.Binding =Text1;
grd.Columns.Add(col);
How do I add image column?or show image in the column?
Please suggest
Dee
As Anvaka said, you can Use DataGridTemplateColumn.
In C# you can add create DataGridTemplateColumn as this, Here i have added a CheckBox in to the DataGridTemplateColumn.
DataGridTemplateColumn col1 = new DataGridTemplateColumn();
col1.Header = "MyHeader";
FrameworkElementFactory factory1 = new FrameworkElementFactory(typeof(Image));
Binding b1 = new Binding("Picture");
b1.Mode = BindingMode.TwoWay;
factory1.SetValue(Image.SourceProperty, b1);
DataTemplate cellTemplate1 = new DataTemplate();
cellTemplate1.VisualTree = factory1;
col1.CellTemplate = cellTemplate1;
datagrid.Columns.Add(col1);
Here Picture is a property of ImageSource type in the class which collection is assigned to ItemsSource of DataGrid.
Use DataGridTemplateColumn. Define cell template in Window.Resources and use FindResource() to set column's CellTemplate property.
Hope this helps.
If you want to Set an Image in a DataGrid Column HEADER,
only programmatically, you can perform like this:
ImageSource image = new BitmapImage(new Uri(#"C:/téléchargement.jpg", UriKind.RelativeOrAbsolute));
Style style = new Style(typeof(DataGridColumnHeader));
FrameworkElementFactory factory = new FrameworkElementFactory(typeof(Image));
factory.SetValue(Image.SourceProperty, image);
factory.SetValue(Image.StretchProperty, Stretch.Uniform);
style.Setters.Add(new Setter { Property = TemplateProperty, Value = new ControlTemplate { TargetType = typeof(DataGridColumnHeader), VisualTree = factory } });
DataZone.Columns[5].HeaderStyle = style;
You can use this method for any type ( Ex : TextBlock , Label, ...), or create a more complex controlTemplate

Resources