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
Related
I'm writing an application that is able to switch language using this.
I also have a combox with two features:
supply help text if no item is selected in combobox (see this)
items are selectable with checkboxes (see this)
My combobox looks like
<Grid>
<ComboBox x:Name="MyCB" SelectionChanged="OnCbObjectsSelectionChanged" ...>
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsSelected}" Checked="OnCbObjectCheckBoxChecked" Unchecked="OnCbObjectCheckBoxChecked" Width="20" />
<TextBlock Text="{Binding Value}" Width="100" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Visibility="{Binding SelectedItem, ElementName=MyCB, Converter={StaticResource Null2Vis}}"
IsHitTestVisible="False"
VerticalAlignment="Center"
Name="tbObjects"
Text="{ns:Loc Var1}"
FontSize="20"
Foreground="Gray"/>
</Grid>
I temporary deactivated the converter with return Visibility.Visible; with no effect.
Whenever I check some checkboxes the combobox.Text property is set and the binding from ns:Loc is overriden. How can I set it again in code if all checkboxes are unchecked?
private void OnCbObjectCheckBoxChecked(object sender, RoutedEventArgs e)
{
StringBuilder sb = new StringBuilder();
foreach (var cbObject in MyCB.Items)
if (cbObject.IsSelected)
sb.AppendFormat("{0}, ", cbObject.Value);
tbObjects.Text = sb.ToString().Trim().TrimEnd(',');
if (tbObjects.Text == "")
{
Binding myBinding = new Binding();
myBinding.Source = TranslationSource.Instance["Var1"]; // <- this does not work :/
myBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
BindingOperations.SetBinding(tbObjects, TextBox.TextProperty, myBinding);
tbObjects.Foreground = new SolidColorBrush(Colors.Gray);
}
}
When all checkboxes are unchecked there is no text in the combobox.
What am I missing?
Edit: Added TextBox element to code
If I understand your code correctly to restore the localization binding you don't need to redefine the Binding - it should be sufficient to use LocExtension with proper argument, because it derives from Binding:
if (tbObjects.Text == "")
{
var myBinding = new LocExtension("Var1");
BindingOperations.SetBinding(tbObjects, TextBox.TextProperty, myBinding);
tbObjects.Foreground = new SolidColorBrush(Colors.Gray);
}
But if for some reason you still want to redefine the Binding, here's what it should look like:
if (tbObjects.Text == "")
{
Binding myBinding = new Binding("[Var1]");
myBinding.Source = TranslationSource.Instance;
myBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
BindingOperations.SetBinding(tbObjects, TextBox.TextProperty, myBinding);
tbObjects.Foreground = new SolidColorBrush(Colors.Gray);
}
Note that the source for the binding is TranslationSource.Instance, and the path should be "[Var1]" to indicate its indexer with "Var1" argument.
Side note
Since TranslationSource.Item[string] indexer is read-only, setting the Binding.UpdateSourceTrigger is reduntant. Also, for the same reason, I'd set Binding.Mode to OneWay.
I am a beginner in Windows phone programming.
I want to bind the data from API to my XAML elements using that Binding Attributes. Please let me know how can we bind multilevel classes objects in it.
Here's my scenario.
List<Sample> SearchResult = new List<Sample>()
{
new Sample(){
Name="ABC",
modelProperty = new SampleDetail(){
articleNo="1", videoURL = "https://www.youtube.com/watch?v=abc",
colors = new List<ColorsDemo>(){
new ColorsDemo {
Name = "Red",
colorProperty= new ColorDemoProperty{ name = "ABC",article_no = "Art1",
image = new Uri("http://img.youtube.com/vi/e60E99tUdxs/default.jpg",UriKind.RelativeOrAbsolute)
}
}
}
}
}
And now, I want to bind the Name of ColorsDemo class into my textblock. See what I have done to bind in XAML like this:
<TextBlock x:Name="PName" Grid.Row="0" Margin="100,0,0,0" Tap="ProductName_Tap" HorizontalAlignment="Center" VerticalAlignment="Center" Width="350" TextWrapping="Wrap" Foreground="Black" Text="{Binding Path=modelProperty.colors.Name}" FontSize="30"></TextBlock>
From your code, i see that colors is a List of ColorDemo objects. So when you say {Binding Path=modelProperty.colors.Name}it does not tell which list item to bind to. The correct usage should be {Binding Path=modelProperty.colors[0].Name}. This tells the control to bind to the name of the first color item (as index is 0).
To bind all the colors. You should use a Listview and bind the colors in it. So you should be able to do something like this.
<ListView ItemSource={Binding Path=modelProperty.colors}>
<ListView.ItemTemplate>
<TextBlock x:Name="PName" Grid.Row="0" Margin="100,0,0,0" Tap="ProductName_Tap" HorizontalAlignment="Center" VerticalAlignment="Center" Width="350" TextWrapping="Wrap" Foreground="Black" Text="{Binding Path=Name}" FontSize="30"></TextBlock>
</ListView.ItemTemplate>
</ListView>
I have to bind dynamic the Text property for the TextBlock in the WPF application in the runtime.
Here is the code:
In xaml file
<DataTemplate x:Key="Double_View_Template">
<TextBlock
x:Name="txtDoubleViewTemplate"
HorizontalAlignment="Left"
VerticalAlignment="Center"
/>
</DataTemplate>
In C#
DataTemplate data = FindResource("Double_View_Template") as DataTemplate;
TextBlock ui = data.LoadContent() as TextBlock;
Binding binding = new Binding();
binding.Path = new PropertyPath("Mass");
BindingOperations.SetBinding(ui, TextBlock.TextProperty, binding);
DataGridTemplateColumn column = new DataGridTemplateColumn();
column.CellTemplate = data;
instrumentDataGrid.Columns.Add(column);
When run the application I see only blank lines, and the values are not shown in the Datagrid. The ItemsSource and the DataContext is correctly set.
If I set
Text="{Binding Path=Mass}"
in the xaml the data is displayed.
Any idea why in the runtime the binding is not set?
In my windows phone app I've implemented data binding which is not yielding me expected results.
My functionality is I've a list box in which I've two textboxes which are data bound.
When I click the textbox datepicker/timepicker will open and the selected value should reflect in the textbox.
The xaml code for the listbox data template is as follows
<TextBox Visibility="{Binding TBVisibility}" IsReadOnly="{Binding TBReadOnly}" InputScope="{Binding Numeric}" AcceptsReturn="{Binding MultiLine}" Width="{Binding TBWidth}" TextWrapping="Wrap" Text="{Binding Path=TBText, Mode=TwoWay}" GotFocus="TextBox_GotFocus_1" KeyUp="TextBox_KeyUp_1" LostFocus="TextBox_LostFocus_1" />
<TextBox Visibility="{Binding TB2Visibility}" IsReadOnly="True" Width="140" Text="{Binding TB2Text, Mode=TwoWay}" GotFocus="TextBox_GotFocus_2" />
I'm launching the datepicker and timepicker as follows
private void LaunchDatePicker(TFDetails field)
{
datePicker = new CustomDatePicker
{
IsTabStop = false,
MaxHeight = 0,
Value = field.SelectedDate
};
datePicker.DataContext = field;
datePicker.ValueChanged += DatePicker_ValueChanged;
LayoutRoot.Children.Add(datePicker);
datePicker.ClickDateTemplateButton();
}
Where as "field" is the datacontext of the listbox.
The ValueChanged events are as follows
private void DatePicker_ValueChanged(object sender, DateTimeValueChangedEventArgs e)
{
DatePicker currentDP = sender as DatePicker;
TFDetails callingField = currentDP.DataContext as TFDetails;
if (callingField != null)
{
callingField.SelectedDate = currentDP.Value;
callingField.TBText = currentDP.ValueString;
}
}
When I change the time its not reflecting in the textbox. I wrote INotifyChangedProperty also.
May I know what mistake I could possible be doing here.
I actually have the same code in a similar UI page where it works perfectly. i don't know what mistake I'm doing here.
Thanks.
ListBox is a collection control. If you have a DataTemplate for it, bindings in it will use a single elements of collection boud to ItemsSource as a DataContext rather than DataContext od entire ListBox.
I have a DataGrid in a user control (DataGridView). This usercontrol propagates a binding to DataGrid's ItemsSource from anywhere in the application and fills it with List of K.
For this example lets define clas for K that has some properties with custom attributes:
public class Foo
{
[Enumeration(IsEnum=true, EnumerationType=typeof(MessageType))] //MessageType is enumeration and is consisted of values: 'Error', 'Warning' and 'Info'
public MessageType MessageType { get; set; }
[Enumeration(IsEnum=true, EnumerationType=typeof(FooType))] //FooType is enumeration and is consisted of values: 'Sweet' and 'Salty'
public FooType FooType { get; set; }
}
DataGrid has an event for autogenerating columns.
private void OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
foreach (Attribute attribute in (e.PropertyDescriptor as System.ComponentModel.PropertyDescriptor).Attributes)
{
Utilities.EnumerationAttribute enumAttribute = attribute as Utilities.EnumerationAttribute;
if (enumAttribute != null
&& enumAttribute.IsEnum)
{
DataGridTemplateColumn templateColumn = new DataGridTemplateColumn();
templateColumn.CellTemplate = (DataTemplate)Resources["enumTemplate"];
e.Column = templateColumn;
}
}
e.Column.IsReadOnly = true;
}
Resource for "enumTemplate" is defined in MergedDictionary as DataTemplate
<DataTemplate x:Key="enumTemplate">
<StackPanel>
<ComboBox/>
</StackPanel>
</DataTemplate>
What I was intending to do is to set ItemsSource of each ComboBox the grid will generate with return value of Enum.GetNames(enumAttribute.EnumerationType) which is of type string[].
Now there is a lot of anonymity here and I don't know names of properties, their types or even the type of object this DataGrid would display during the run time.
I had several tries into this ... like defining a property DataSourcesList of type List> where NamedArray holds items to fill the combobox and a name of the property (from e.PropertyName) so that I know which of the NamedArray to use for combobox being generated ... something like:
DataSourcesList.Add(new DataSourceWithMappedName<System.Object>() { MappedName = e.PropertyName, SourceList = Enum.GetNames(enumAttribute.EnumerationType) });
And then altering DataTemplate:
<DataTemplate x:Key="enumTemplate">
<DataTemplate.Resources>
<converters:IListToItemsSource x:Key="ilistToItemsSource"/>
</DataTemplate.Resources>
<StackPanel>
<ComboBox ItemsSource="{Binding DataSourcesList, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:DataGridView}}, Converter={StaticResource ilistToItemsSource}, ConverterParameter={Binding somethingButAllInVaine}}"/>
</StackPanel>
</DataTemplate>
, but this can't be done since ConverterParameter is not a DependencyObject and can not be bound.
Maybe I should state that the same principle should be later used for binding collections and not just enums.
So please, can anyone help me with a solution to generic ComboBox representation in a generic GridView.
Tnx and happy coding.
Perhaps it would be easier to set the DataTemplate up in code. Start by defining the datatemplate and then setting the ComboBox ItemSource Binding Source to the List of String resulting from the Enum.GetNames().
Code Way
// Create template
DataTemplate newTemplate = new DataTemplate();
FrameworkElementFactory stackFactory = new FrameworkElementFactory(typeof(StackPanel));
FrameworkElementFactory comboFactory = new FrameworkElementFactory(typeof(ComboBox));
Binding newBinding = new Binding();
newBinding.Source = Enum.GetNames(typeof(enumAttribute.EnumerationType));
comboFactory.SetBinding(ComboBox.ItemsSourceProperty, newBinding);
stackFactory.AppendChild(comboFactory);
newTemplate.VisualTree = stackFactory;
// Set the template
templateColumn.CellTemplate = newTemplate;
XAML / Code Way*
<CollectionViewSource x:Key="EnumCollection"/>
<DataTemplate x:Key="enumTemplate">
<StackPanel>
<ComboBox ItemsSource="{Binding Source={StaticResource EnumCollection}}" />
</StackPanel>
</DataTemplate>
Code (Make sure you set the Collection Source):
CollectionViewSource enumCollection = (CollectionViewSource)this.FindResource("EnumCollection");
enumCollection.Source =Enum.GetNames(typeof(enumAttribute.EnumerationType));
Pure Xaml
<ObjectDataProvider x:Key="EnumCollection"
MethodName="GetValues"
ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="YourEnum" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<DataTemplate x:Key="enumTemplate">
<StackPanel>
<ComboBox ItemsSource="{Binding Source={StaticResource EnumCollection}}" />
</StackPanel>
</DataTemplate>