How do you bind a DataRow to a TextBlock? - wpf

I have Window. Window.DataContext = DataRow.
and i have TextBlock.
I need to bind DataRow.Array[0] to the Text property of a TextBlock.
how do I do it?
edit:
<Window x:Class="Client.payment.CheckMore"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpf="http://schemas.microsoft.com/wpf/2008/toolkit" Loaded="Window_Loaded" x:Name="p_this">
<DockPanel>
<TextBlock x:Name="p_idCheck" Text="{Binding Path=Array[0]}"/>
</DockPanel>
</Window>
in code: this.DataContext = dateRow.Rows[0];

The Property you're looking for is probably ItemArray. You can bind to it like this, the following ways will give you the same result (if the first Column is named Column1).
The first example binds to the first item in ItemArray
The second example binds to the value of the first Column
The third example binds to the value of the Column named Column1. This is the recommended approach since it will still work even if your Columns change order.
Xaml
<StackPanel>
<TextBlock x:Name="p_idCheck"
Text="{Binding Path=ItemArray[0]}"/>
<TextBlock x:Name="p_idCheck2"
Text="{Binding Path=[0]}"/>
<TextBlock x:Name="p_idCheck3"
Text="{Binding Path=[Column1]}"/>
</StackPanel>
Code behind example
private DataSet m_dataSet = null;
public MainWindow()
{
InitializeComponent();
m_dataSet = new DataSet();
DataTable dataTable1 = new DataTable("Table1");
dataTable1.Columns.Add("Column1", typeof(string));
m_dataSet.Tables.Add(dataTable1);
DataRow dataRow1 = dataTable1.NewRow();
dataRow1["Column1"] = "Column1Value";
dataTable1.Rows.Add(dataRow1);
this.DataContext = dataRow1;
}

<TextBlock Text = "{Binding Array[0]}" ...
works fine if Array is public property.

Related

Binding dynamically generated textblock WPF MVVM Light

I am using MVVMM Light WPF and I want to do the following: Generate textboxes dynamically and bind them to a property of a class.
I already have the following but it doesn't show up in my view when running the application.
This is my collection:
private ObservableCollection<Border> _controllekes;
public ObservableCollection<Border> Controllekes
{
get { return _controllekes; }
set
{
_controllekes = value;
RaisePropertyChanged("Controllekes");
}
}
This it my xaml:
<ItemsControl ItemsSource="{Binding Path=Controllekes}">
</ItemsControl>
This is a part where I fill the itemsource "Controllekes":
Controllekes = new ObservableCollection<Border>();
Border border = new Border();
border.BorderThickness = new System.Windows.Thickness(5);
border.BorderBrush = Brushes.AliceBlue;
border.Padding = new System.Windows.Thickness(5);
TextBlock tb = new TextBlock();
tb.Background = Brushes.Red;
Binding nameTextBinding = new Binding("Controllekes");
nameTextBinding.Path = new System.Windows.PropertyPath(this.Dossier.Omschrijving);
nameTextBinding.Mode = BindingMode.OneWay;
//nameTextBinding.Source = this.Dossier.Omschrijving;
tb.SetBinding(TextBlock.TextProperty, nameTextBinding);
border.Child = tb;
this.Controllekes.Add(border);
What it does it creates a border with in this border a textblock where the binding should happen. I whish to bind the property this.Dossier.Omschrijving (Dossier is the class). If I just enter a string in the textbox it works.
In runtime the border gets generated but the textblock remains empty. The object Dossier.Omschrijving contains information.
What do I do wrong?
EDIT:
safe put me in the right direction and the answer of ItemsControl with multiple DataTemplates for a viewmodel made me finish the job :)
through all that and use ItemTemplate
<ItemsControl x:Name="ic">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<CheckBox IsChecked="{Binding yourboolProperty}"/>
<TextBlock Background="Red" Text="{Binding yourStringProperty}"></TextBlock>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
and set ic's ItemsSource to List

In WPF, is it possible to bind values to controls in a loop?

I have a series of TextBlock Controls, like this:
<TextBox Name="tb1"/>
<TextBox Name="tb2"/>
<TextBox Name="tb3"/>
<TextBox Name="tb4"/>
And I have a list of values that I'd like to bind to those text boxes, say in a list:
List<String> texts = new List<String>();
texts.Add("test1");
texts.Add("test2");
texts.Add("test3");
texts.Add("test4");
Currently, what I have to do is manually set the values of the TextBoxes, like this:
tb1.Text = texts[0];
tb2.Text = texts[1];
tb3.Text = texts[2];
tb4.Text = texts[3];
Is it possible to do this in a loop somehow? Perhaps change the XAML to take in a list or programatically get the TextBoxes? Thanks a lot in advance.
<ItemsControl Items="{Binding myValues}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding}"></TextBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
In your code behind declare a property:
public string myValues { get return new[] { "foo", "bar" }; }
and in the code behind constructor set this control to its datacontext:
this.DataContext = this;
You can access indexed values in your binding - no loop required. Check this previous SO answer from Ivan Towlson. Ivan uses a string indexer in that example, but you can use a numeric one as well.

XAML Code for TREEVIEW

Following is the code I wrote for generating treeview hierarchy,
For Each k As KeyValuePair(Of String, GenreSet) In GenreSetDictionary
Dim t As New TreeNodeSet
t.Genre = True
t.Imagepath = k.Value.IconPath
t.Namee = k.Key
Dim pnode As New TreeViewItem
pnode.DataContext = t
pnode.Visibility = True
For Each z As DatabaseDearDataSet.DiskListRow In adpt.GetDataByGenre(t.Namee)
Dim tt As New TreeNodeSet
tt.Genre = False
tt.Imagepath = IconDictionary(z.DiskIcon).IconPath
tt.Namee = z.DiskName
Dim cnode As New TreeViewItem
cnode.DataContext = tt
pnode.Items.Add(cnode)
Next
DisksTreeView1.Items.Add(pnode)
Next
Following is the code I have used in XAML:
<TreeView Height="211" HorizontalAlignment="Left" Margin="19,15,0,0" Name="TreeView1" VerticalAlignment="Top" Width="346">
<TreeView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding ImagePath}" Width="32" Height="32"/>
<TextBlock Text="{Binding Namee}" VerticalAlignment="Center" HorizontalAlignment="Center" />
</StackPanel>
</DataTemplate>
</TreeView.ItemTemplate>
</TreeView>
However, I was not able to get that work, could you please tell me where my XAML went wrong please.
I see few minor mismatches here: the name of the TreeView control (TreeView1 or DisksTreeView1) and the ImagePath property (or Imagepath, c# is sensible to the register of variables).
But the main reason of the incorrect behavior is that the ItemTemplate property is applied to the ItemsSource property, not to the Items property.
Here are two possible ways to correct the code:
1) Fixeing of the data class, item template and binding to the ItemsSource
Create the myObservableCollection private field of the type ObservableCollection(Of TreeNodeSet).
Add to the constructor the line DisksTreeView1.ItemsSource = myObservableCollection
Change the line DisksTreeView1.Items.Add(pnode) to the line myObservableCollection.Add(t).
Add the Disks property to the TreeNodeSet class (the type is ObservableCollection too)
In the xaml replace the line with DataTemplate to the line <HierarchicalDataTemplate ItemsSource="{Binding Disks}"
Change the line pnode.Items.Add(cnode) to the line t.Disks.Add(tt).
2) Using the HeaderTemplate property instead of the ItemTemplate property.
At first, move the DataTemplate to resources and add some key. Then add a similar code near each TreeViewItem in the code-behind:
Dim pnode As New TreeViewItem
pnode.DataContext = t
pnode.Header = t
pnode.HeaderTemplate = Resources("someKey")

Setting multiple Datacontext

I am trying to find out how to set correctly multiple DataContexts in XAML page. I have a basic collection that I create in code behind and set ItemSource Binding og AutoCompleteBox to it. At the same time, I have another datacontext to set labelsDataSource inside the grid. If I set this datacontext, the AutoCompleteBox’s itemsSource binding is lost. AutoCompleteBox is inside that grid. I do assign DataContext directly to the objetc this way:
MyAutoCompleteBox.DataContext = this;
I am wondering if there is a better way to do it?
Thank you in advance for the help!
Setting AutoComplete Box:
<sdk:AutoCompleteBox x:Name="MyAutoCompleteBox" IsTextCompletionEnabled="True" ItemsSource="{Binding Items}" />
Code Behind:
public IList<string> Items
{
get;
private set;
}
public Basic_ChildWindow()
{
InitializeComponent();
Items = new List<string>();
Items.Add(#"One");
Items.Add(#"Two");
Items.Add(#"Three");
DataContext = this;
}
Another datacontext in the same XAML page, AutoCompleteBox is inside that grid:
<Grid x:Name="grdBasic_ChildWindow_Right" Style="{StaticResource GridStyle}" DataContext="{Binding Source={StaticResource LabelsDataSource}}">
I'm not sure I understand your question--what is "labelsDataSource"?
However, if what you have posted is all the code and there is nothing more to it, simply remove the datacontext/binding from the grid. The grid does not need a datacontext set (it is simply a visual container--not data-related).
So change this:
<Grid x:Name="grdBasic_ChildWindow_Right" Style="{StaticResource GridStyle}" DataContext="{Binding Source={StaticResource LabelsDataSource}}">
To this:
<Grid x:Name="grdBasic_ChildWindow_Right" Style="{StaticResource GridStyle}">

Displaying FontFamily in Combobox

My goal is to manipulate the text-styles of my application via DependencyProperties. I got a diagram in which the texts are to be manipulated in size, fontfamily, color, etc. So I'd like to use an interface similar to a rich text editor like Word.
I'm using this code in my TextStyleVM http://shevaspace.blogspot.com/2006/12/i-have-some-fun-with-formattedtext_14.html
So I have a FontFamilyProperty and a Getter and Setter for it:
public static DependencyProperty FontFamilyProperty =
DependencyProperty.Register(
"FontFamily",
typeof(FontFamily),
typeof(OutlinedText),
new FrameworkPropertyMetadata(
SystemFonts.MessageFontFamily,
FrameworkPropertyMetadataOptions.AffectsRender |
FrameworkPropertyMetadataOptions.AffectsMeasure),
new ValidateValueCallback(IsValidFontFamily));
public FontFamily FontFamily
{
get { return (FontFamily)base.GetValue(FontFamilyProperty); }
set { base.SetValue(FontFamilyProperty, value); }
}
Then there is a ToStyle method, which sets the style for the labels of the diagram, which are to be manipulated:
Style style = new Style();
Binding fontFamilyBinding = new Binding("FontFamily");
fontFamilyBinding.Source = this;
Setter fontFamilySetter = new Setter();
fontFamilySetter.Property = TextBlock.FontFamilyProperty;
fontFamilySetter.Value = fontFamilyBinding;
style.Setters.Add(fontFamilySetter);
return style;
Now this works for a TextBox. The textbox displays the current FontFamily, and if I enter a new, valid FontFamily like Arial into the textbox the FontFamily of the labels are changed.
However, what I'd like to have is a combobox, which displays the SystemFonts and where I can choose one FontFamily for my labels. However, the binding doesn't seem to work. Neither the system fonts nor the current fonts of the labels are displayed. The combobox is just empty.
This is my xaml:
<r:RibbonLabel Content="FontFamily" />
<!--these do not work-->
<r:RibbonComboBox SelectedItem="{Binding FontFamily}"/>
<r:RibbonComboBox ItemsSource="{Binding FontFamily}"/>
<!--this works-->
<r:RibbonTextBox Text="{Binding FontFamily}"/>
Now, I assume I have to set a different Setter for a ComboBox in the ToStyle Method. But I have no clue, which one. Maybe someting like this:
fontFamilySetter.Property = ComboBox.ItemSource;
However, if I set that Property, the TextBox still works. So is this the wrong place to start at? I'd also be grateful if someone could hint me to some documentation about using these Style-, Setter-, Binding-key-words, which are used in the ToStyle method, since this is somebody elses code I'm working with.
ItemsSource here expects a collection; e.g. Fonts.SystemFontFamilies
<ComboBox ItemsSource="{Binding Source={x:Static Fonts.SystemFontFamilies}}"/>
Actually, here's a very nice link covering font selection:
http://www.hanselman.com/blog/LearningWPFWithBabySmashCustomerFeedbackAndAWPFFontComboBox.aspx
Scott Hanselman even shows how to render each font item in combobox with it's own font family.
Added per OP comment.
Here's an example of binding to dependency property. Property is named "MyFontFamily" to avoid collision with existing Window's property. Sorry, no Ribbon controls (I have bare 3.5 sp1).
Window1.xaml
<Window
x:Class="SimpleWpf.Window1"
x:Name="ThisWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel Orientation="Vertical">
<ComboBox
SelectedItem="{Binding MyFontFamily, ElementName=ThisWindow}"
ItemsSource="{Binding Source={x:Static Fonts.SystemFontFamilies}}"/>
<TextBlock
Text="Lazy dog jumper"
FontFamily="{Binding MyFontFamily, ElementName=ThisWindow}"
FontSize="24"/>
</StackPanel>
</Window>
Window1.xaml.cs
public partial class Window1 : Window
{
// ...
public static readonly DependencyProperty MyFontFamilyProperty =
DependencyProperty.Register("MyFontFamily",
typeof(FontFamily), typeof(Window1), new UIPropertyMetadata(null));
}
A just in Xaml solution with fonts sorted in alphabetical order:
<Window x:Class="WpfFontsComboBox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:System="clr-namespace:System;assembly=mscorlib"
xmlns:ComponentModel="clr-namespace:System.ComponentModel;assembly=WindowsBase"
Height="350" Width="525">
<Window.Resources>
<CollectionViewSource x:Key="SortedFontsCollection" Source="{Binding Source={x:Static Fonts.SystemFontFamilies}}" >
<CollectionViewSource.SortDescriptions>
<ComponentModel:SortDescription PropertyName="Source" />
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</Window.Resources>
<StackPanel>
<Label Content="42" FontFamily="{Binding ElementName=comboBoxFonts, Path=SelectedItem}" />
<ComboBox x:Name="comboBoxFonts" ItemsSource="{Binding Source={StaticResource SortedFontsCollection}}" />
</StackPanel>
</Window>
A great Font Combobox for WPF can be found here:
CodeProject.com: A XAML-Only Font ComboBox
It is pure XAML, can be just copied/pasted and even sorts the fonts properly. The article also describes nicely all the gotchas encountered and how to solve them.

Resources