I just want to add a ToolTip for each item in a Silverlight Custom ComboBox. so when a user moves around items can see ToolTip, items in ComboBox will be of type string and the same value will be displayed as ToolTip.
You can create a tooltip by adding a simple data template -- give the template TextBlock with the tool tip added:
<ComboBox>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock ToolTip="{Binding}" Text="{Binding}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Edit - Using Code behind
var dt = new DataTemplate();
var tb = new TextBlock();
tb.ToolTip = new Binding(".");
tb.Text = new Binding(".");
dt.VisualTree = tb;
var cb = new ComboBox();
cb.ItemTemplate = dt;
Related
I want to add 2-3 buttons to the rows in the last column of my datagrid using the backend C# and not XAML. I managed to add one button to the cells but I'm having trouble adding anymore past that.
I have tried creating a new FrameworkElementFactory and adding it into the column but it just replaces the previous button instead of adding the button.
DataGridTemplateColumn buttonColumn = new DataGridTemplateColumn();
buttonColumn.Header = "Actions";
buttonColumn.Width = 209;
DataTemplate buttonTemplate = new DataTemplate();
FrameworkElementFactory buttonFactory = new FrameworkElementFactory(typeof(Button));
buttonTemplate.VisualTree = buttonFactory;
buttonFactory.AddHandler(ButtonBase.ClickEvent, new RoutedEventHandler(Activate));
buttonFactory.SetValue(ContentProperty, "A");
buttonColumn.CellTemplate = buttonTemplate;
dGrid_SavedData.Columns.Add(buttonColumn);
Regardless of whether you create it programmatically or in XAML, a DataTemplate can only have single root element so you should set the VisualTree property to a FrameworkElementFactory for a Panel and use the AppendChild method to add the button factories to the panel factory, e.g.:
DataGridTemplateColumn buttonColumn = new DataGridTemplateColumn();
buttonColumn.Header = "Actions";
buttonColumn.Width = 209;
DataTemplate buttonTemplate = new DataTemplate();
FrameworkElementFactory panelFactory = new FrameworkElementFactory(typeof(StackPanel));
buttonTemplate.VisualTree = panelFactory;
FrameworkElementFactory buttonAFactory = new FrameworkElementFactory(typeof(Button));
buttonAFactory.AddHandler(ButtonBase.ClickEvent, new RoutedEventHandler(Activate));
buttonAFactory.SetValue(ContentProperty, "A");
FrameworkElementFactory buttonBFactory = new FrameworkElementFactory(typeof(Button));
buttonBFactory.AddHandler(ButtonBase.ClickEvent, new RoutedEventHandler(Activate));
buttonBFactory.SetValue(ContentProperty, "B");
panelFactory.AppendChild(buttonAFactory);
panelFactory.AppendChild(buttonBFactory);
buttonColumn.CellTemplate = buttonTemplate;
dGrid_SavedData.Columns.Add(buttonColumn);
So, I’m on an iPad, so I can’t give much detail. First let me say that this is a very hard way to do this and I recommend just about anything else. But if you absolutely have to fully dynamically generate your grid, you need to put the button in a container. For example, a vertical stack panel. Then you can add as many buttons as you want. Good luck!
Here is the Code Snippet
<DataGrid x:Name="dgStudent" d:ItemsSource="{d:SampleData ItemCount=5}" Margin="0,44,0,0" Grid.RowSpan="2">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Edit">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Name="btnEdit" Content="Edit" Click="btnEdit_Click" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Delete">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Name="btnDelete" Content="Delete" Click="btnDelete_Click" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
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:
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding MyImage}" >
<Image.ToolTip>
<ToolTip >
<StackPanel>
<Image Source="{Binding MyBigImage}" />
</StackPanel>
</ToolTip>
</Image.ToolTip>
</Image>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
But I need to move the code in the c# side. So I've tried this code:
DataGridTemplateColumn col1 = new 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.SetValue(TextBlock.DataContextProperty, this.pieces);
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;
grdDataItems.Columns.Add(col1);
cellTemplate1.Seal();
In the datagrid cell of the column I see the correct image from "MyImage", but in the tooltip of the cell I see always the image of the first element of the collection of "MyBigImage".
How can I solve this?
Regards
How to: Fill a ListView by using C# instead of using XAML
I would like to fill a ListView by using C# (WPF), not by using XAML. The reason for this is, that we do not know the number of elements before runtime.
This is my working XAML code:
<ListView Name="listView_BusinessContacts" SelectionMode="Single">
<ListViewItem Selected="ListViewItem_Selected">
<DockPanel DockPanel.Dock="Top" Name="dockPanel_1">
<Image DockPanel.Dock="Left" Source="/X;component/Images/folder.png" Stretch="None" />
<Label Content="Test 123" DockPanel.Dock="Right" Name="label_1" />
</DockPanel>
</ListViewItem>
</ListView>
My idea is first to create the ListViewItem. After that, I could create the DockPanel. But now, I do not know, how to add two elements to a DockPanel (here: Image and Label). After that, I would add the DockPanel to the ListViewItem and than I would add that ListViewItem to the ListView.
I hope, that you understand what I want to do.
Solution by SynerCoder:
public void SetListViewItems()
{
foreach (var item in File.ReadAllLines(#"C:\Companies\Companies.txt", Encoding.UTF8))
{
Image image = new Image();
image.Source = new BitmapImage(new Uri(#"Images\folder.png", UriKind.Relative));
image.Stretch = Stretch.None;
Label label = new Label();
label.Content = "Test 123";
DockPanel.SetDock(image, Dock.Left);
DockPanel.SetDock(label, Dock.Right);
DockPanel dockPanel = new DockPanel();
dockPanel.Children.Add(image);
dockPanel.Children.Add(label);
ListViewItem listViewItem = new ListViewItem();
listViewItem.Content = dockPanel;
listView_BusinessContacts.Items.Add(listViewItem);
}
}
You can use the following code to create your listview, use the static SetDock method of the DockPanel to set the docking positions.
var listView = new ListView();
foreach (var item in something)
{
var image = new Image();
image.Source = ...;
image.Stretch = Stretch.None;
var label = new Label();
label.Content = "Test 123";
DockPanel.SetDock(image, Dock.Left);
DockPanel.SetDock(label, Dock.Right);
var dockPanel = new DockPanel();
dockPanel.Children.Add(image);
dockPanel.Children.Add(label);
var item = new ListViewItem();
item.Content = dockPanel;
listView.Items.Add(item);
}
How can I create this from code ?
<CheckBox Command="{Binding Source={StaticResource VMLocator}, Path=TimeTableInformationViewModel.MyCommand }"
CommandParameter="{Binding valueFromInput}" />
I am not sure how to set Command property from behind code :
public static DataTemplate CreateDataTemplate()
{
var block = new FrameworkElementFactory(typeof(CheckBox));
block.SetBinding(CheckBox.CommandProperty, new Binding(""));
DataTemplate newDataTemplate = new DataTemplate() { VisualTree = block };
}
Try this:
TypeOfYourObject vmLocator = (TypeOfYourObject)Resources["VMLocator"];
CheckBox checkBox = new CheckBox();
checkBox.Command = vmLocator.TimeTableInformationViewModel.MyCommand;
checkBox.CommandParameter = vmLocator.valueFromInput;
UPDATE >>>
There are a number of ways of doing this, but I have included a simple example that includes setting up a Binding... for more than this, please refer to the How do I build a DataTemplate in c# code? post to find out how to create a larger DataTemplate in code.
FrameworkElementFactory checkbox = new FrameworkElementFactory(typeof(CheckBox));
checkBox.Name = "aCheckBox";
checkBox.SetBinding(TextBlock.IsCheckedProperty, new Binding("YourBoolProperty"));
DataTemplate dataTemplate = new DataTemplate() { VisualTree = checkbox };
I am trying to Bind the TextBlock inside ComboBox through Code. I am able to bind the textblock sucessfully but For some reasons TextBlock doesnt display Text Values.
I have mechanism which checks for the selected values and there I am getting the selected values without any problem.
So to conclude, My binding is working fine but I am missing out something hence textblock is not displaying text that is bound with it.
This is the code I am using for Binding:
where "lObjTextBlock" is TextBlock inside of ComboBox.
TextBlock lObjTextBlock = (TextBlock)ComboBox.ItemTemplate.LoadContent();
Binding lObjBinding = new Binding();
lObjBinding.Path = new PropertyPath("[" + lObjMap.PropertyName + "]");
lObjTextBlock.SetBinding(TextBlock.TextProperty, lObjBinding);
This is the XAML for the TextBlock:
<my:HComboBox Name="cmbRefDoctor">
<my:HComboBox.ItemTemplate>
<DataTemplate>
<TextBlock x:Name="txtRefDoctorName" />
</DataTemplate>
</my:HComboBox.ItemTemplate>
</my:HComboBox>
Once again : My problem is that TextBlock is not displaying any Text althought values are being set.
Would love to get all possible suggestions. Thanks in advance.
it's one of the way to bind controls which inside datatemplate
this.DataContext = Person;
Binding binding = new Binding();
binding.Source = ob;
DataTemplate dtemp = (DataTemplate)Resources["PointTemp"];
Border bdr = dtemp.LoadContent() as Border;
TextBlock tblk = bdr.Child as TextBlock;
tblk.SetBinding(TextBlock.TextProperty, binding);
Here I used ob as double collection assign to textproperty by binding source
<UserControl.Resources>
<DataTemplate x:Key="PointTemp">
<Border Margin="0,23,0,0" Background="Transparent">
<TextBlock Text="{Binding}" Foreground="White" FontSize="28" HorizontalAlignment="Center" VerticalAlignment="Center" TextAlignment="Center"/>
</Border>
</DataTemplate>
</UserControl.Resources>
And you can assign,
if it's combobox or listbox
Here Person is a class name, or set the class name in combobox itemsource