I have bound a ComboBox to a list of DateTime values to select a start time for an event. I am using an ItemTemplate to specify the formatting of the DateTime in the list. I also want the user to be able to manually specify a start time not in the list, like 8:27 AM or 9:30 PM.
Wiring that up is not the issue; rather, I want the user to be presented with the same formatted DateTime as the list.
<ComboBox x:Name="StartTimeButton"
ItemsSource="{Binding DataContext.StartTimes,
RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
SelectedItem="{Binding DefaultStartTime}"
IsEditable="True">
<ComboBox.ItemTemplate>
<DataTemplate>
<Label>
<TextBlock Text="{Binding StringFormat='{}{0:hh:mm tt}'}" />
</Label>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
This results in:
I have been unable to determine how to format the top TextBlock used by the ComboBox (when editing is enabled) to match the formatting of the dropdown area.
The ultra shorthand that gets you halfway there (you can drop the DataTemplate):
<ComboBox ItemsSource="{Binding Times}"
IsEditable="True" ItemStringFormat="hh:mm tt"
TextSearch.TextPath="Hour"/>
The problem is, that DateTime has no property that outputs the time in that format. Personally, i would write a wrapper that has an internal DateTime and a property that facilitates formatting to string and parsing from it.
There does not appear to be a standard way of creating a new item form the entered text, so you might need to parse the ComboBox.Text manually in case a value is entered that is not in the list.
Related
While trying to convert usual wpf fields to the custom fields that the program I need to modify, I came across an issue of having 2 different data sources.
1) The data source that retrieves/inserts data to fill this combobox (DataSource)
2) The data source that takes care of other UI elements (DSP)
As when certain items are selected from the combobox, not only does it get stored with the other information in the form, but it may show/hide another UI element.
I am trying to convert:
<ComboBox Name="tempComboBox"
ItemsSource="{Binding Source={StaticResource DataSource}, Path=Value.Properties[temp].MetaData.Lookups}"
DisplayMemberPath="Description"
SelectedValuePath="Value"
SelectedValue="{Binding Source={StaticResource DSP}, Path=Value, ValidatesOnDataErrors=True}"
Style="{StaticResource tempComboStyle}"/>
Into something like this:
<ctrls:Fields Name="tempComboBox"
FieldName="temp"
DataContext="{Binding Source={StaticResource DataSource}, Path=Value, ValidatesOnDataErrors=True}"
Style="{StaticResource tempComboStyle}"/>
However, this WILL NOT work as it only stores the data, but does not hide/show elements when the specific item is selected.
I have tried multi binding, which does not work. Surrounding the combobox tags with the ctrls:Fields tag, again doesn't work. And combining the DataContext property with both SelectedValue and ItemSource, none of which work.
I do not have any way of getting to the code behind of this form either, it must be strictly done through XAML.
Thank you for any help!
I have an xceed:DataGridControl with bounded ItemsSource. Currently I'm trying to set my in/visible columns and the title/headertext for each visible column. Preferably I would like to bind a property in my ViewModel, to set the in/visible columns and theirs titles. But I find no way I could do it. Does anyone know a solution to this problem?
<xceed:DataGridControl
x:Name="dataGridControl"
SelectedItem="{Binding SelectedTextItem, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
ItemsSource="{Binding ItemsSourceData, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" >
</xceed:DataGridControl>
Yes indeed I had to deal with xceed's controls few months ago.
DataGridControl allows you to generate columns automantically. That is also its default behavior.
In order to have your own columns you will have to disable the property AutoCreateColumns and futhermore you will have to set few columns on the property DataGridControl.Columns.
There you will be able to bind Visible property of the Column.
Thanks to Peter for providing this code:
<xceed:DataGridControl ItemsSource="{Binding TextSet}" >
<xceed:DataGridControl.Columns>
<xceed:Column FieldName="ColumnId" Title="{Binding DatagridTitle[ColumnId], Mode=OneWay}" Visible="True" />
</xceed:DataGridControl.Columns>
</xceed:DataGridControl>
I also met similar issue.
You can use the Visible property, then do following:
<xcdg:ColumnFieldName="ColumnId" Title="ColumnId"
Visible="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type typeOfAncestor}}, Path=DataGridControl.DataContext.BooleanSourceProperty}"/>
For example, if the typeOfAncestor is xcdg:MergedColumn and BooleanSourceProperty is IsVisble, then the code should be:
<xcdg:ColumnFieldName="ColumnId" Title="ColumnId"
Visible="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type xcdg:MergedColumn}}, Path=DataGridControl.DataContext.IsVisible}"/>
Then the issue can be solved.
I can't get my custom DateTime string format to work in my binding. I want the format to be "mmmm, yyyy" (e.g. "June, 2012").
The following does not work. I get a short date format (m/d/yyyy).
<TextBlock Text="{Binding ElementName=ThisWindow,
Path=Date,
StringFormat={}{0:MMMM\, yyyy}"/>
I've considered using a converter, but I prefer a pure XAML approach.
Edit:
For clarity, I have a Window with a dependency property Date of type DateTime. In my XAML, I've named the window 'Thiswindow'.
Edit 2:
I looked back at my actual code, and I had a Label, not a TextBlock. I changed it to TextBlock and it works fine.
<Label Content="{Binding ElementName=ThisWindow,
Path=Date,
StringFormat={}{0:MMMM\, yyyy}"/>
Anyone know why it doesn't work with Label?
Thanks.
ContentControls have a ContentStringFormat property which overrides the original formatting.
(When i saw your question i expected this to be the problem actually but was surprised to find a TextBlock at first)
Your month needs to be in uppercase:
{Binding Source={x:Static sys:DateTime.Now}, StringFormat={}{0:MMMM\, yyyy}}
EDIT:
The Label problem is probably because Label has Content, not Text.
Change the Text="{Binding ...}" to Content="{Binding ...}"
In the below code, Combobox is wired to NameInfo object along with a converter.NameInfoConverter returns a format in which items in combobox are shown in a particular format (for eg: LastName, FirstName (Badge#) )
Now, when I set TextSearch.Text="{Binding NameInfo, Converter={StaticResource NameInfoConverter}, ConverterParameter=true}" on combobox; TextSearch doesn't work. When I set TextSearch.TextPath="Name", search itself works but doesnot get the correct format displayed in the selectionbox of combobox.
Any Ideas?
<StackPanel>
<ComboBox x:Name:"cmbName">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name,
Converter={StaticResource NameInfoConverter}, ConverterParameter=true}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
You've probably hit a limitation in the API. I suggest you take an alternative route and bind directly to a property that is correctly formatted for your textblock.
If this is a serious app, you may want to look into using the MVVM pattern and place your converted/formatted property in the viewmodel. Otherwise, just create a new property on your databound class called NameInfo or something and do the conversion from that.
I have a datagrid. A column of the datagrid is a simple <DataGridTemplateColumn> with its CellTemplate containing a <DataTemplate> which contains a <ComboBox> such as
<my:DataGrid Name="dataGridMain" AutoGenerateColumns="False">
<my:DataGrid.Columns>
<my:DataGridTemplateColumn Header="Food" >
<my:DataGridTemplateColumn.CellTemplate >
<DataTemplate>
<ComboBox Name="comboDataTemplate"
Text="{Binding Path=Food,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Source={StaticResource resFoodLookups}}"
DisplayMemberPath="FoodName"
SelectedValuePath="FoodID" IsEditable="True" />
</DataTemplate>
</my:DataGridTemplateColumn.CellTemplate>
</my:DataGridTemplateColumn>
</my:DataGrid.Columns>
</my:DataGrid>
All is working fine. Each combobox is bound to a static list due to the ItemsSource="{Binding Source={StaticResource resFoodLookups}}" statement.
But my requirement is that this list will change from row-to-row.
That is: each time a user types a new entry in the combobox list on one row, I want to have it available in the selection on the next row.
Basically, I want to create a new list for the user each time the user inserts a new word in the combobox on any of the rows. (The combobox is editable).
Now, I can wire up the "ItemsSource=..." at run-time, but I'm only able to do this once thus the <DataTemplate> propagates the 'same' list to 'all' the comboboxes on 'all' the rows.
My thoughts are that I need to change the ItemsSource=... property on an object-by-object basis on each combobox that is created in memory after the DataTemplate has created them - but I have no idea how to do this.
What you need to do is perform 2 way data binding to your the ItemsSource, this way when the ItemSource is updated in one of the combo boxes it will auto update your original collection and therefore your other combo boxes as well.
What I normally do is use the MVVM pattern. It is worth some research if you are not already using a particular pattern on your application.
Using it to solve your problem i would do the following:
Create a ViewModel (Lets call it MyViewModel) which has a collection of values called 'MyComboBoxItems' (It is important that you use ObservableCollection for the databinding to work)
When I create the Window/Control that contains your table, I also create an instance of MyViewModel and set its the Window.DataContext=myViewModelInstance
For your combobox binding use ItemsSource="{Binding Path=MyComboBoxItems, Mode=TwoWay}