I have an Infragistics WPF XamDoughnutChart which displays data binded from an ObservableCollection called Data and shows Data.Value and Data.Label on its chart labels.
<Grid>
<ig:XamDoughnutChart x:Name="MyDonut"
CenterData="{Binding TotalItemCount}">
<ig:XamDoughnutChart.Series>
<ig:RingSeries ItemsSource="{Binding Data}"
ValueMemberPath="Value"
LabelMemberPath="Label">
</ig:RingSeries>
</ig:XamDoughnutChart.Series>
</ig:XamDoughnutChart>
</Grid>
I am trying to change the LabelTemplate as mentioned here: https://www.infragistics.com/help/wpf/16.2/infragisticswpf.controls.charts.xamdatachart~infragistics.controls.charts.hierarchicalringseries_members
But nothing I try works. Here is my new XAML with all my attempts:
<Window.Resources>
<DataTemplate x:Key="MyLabelTemplate">
<Label Foreground="Blue" Content="test"/> <-- **This shows 'test' in blue
<Label Foreground="Blue" Content="{Binding}"/> <-- Does nothing
<Label Foreground="Blue" Content="{Binding Path=Label}"/> <-- Does nothing
<Label Foreground="Blue" Content="{Binding Path=Value}"/> <-- Does nothing
</DataTemplate>
</Window.Resources>
<Grid>
<ig:XamDoughnutChart x:Name="MyDonut"
CenterData="{Binding TotalCount}">
<ig:XamDoughnutChart.Series>
<ig:RingSeries ItemsSource="{Binding Data}"
ValueMemberPath="Value"
LabelMemberPath="Label"
LabelTemplate="{StaticResource MyLabelTemplate}"> <-- **Add a LabelTemplate**
</ig:RingSeries>
</ig:XamDoughnutChart.Series>
</ig:XamDoughnutChart>
</Grid>
How can I actually change this labels template?
SOLVED
<ig:RingSeries.LabelTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Item.Label}" Foreground="White"/>
</StackPanel>
</DataTemplate>
</ig:RingSeries.LabelTemplate>
Related
What is a good way to get rid of repeating XAML in different files. Example :
<StackPanel Grid.Row="8" Grid.Column="2" Style="{StaticResource ViewContentStyle}" Visibility="{Binding Type, Converter={StaticResource TypeToVisibility}}">
<ctl:NewLabel LabelContent="{x:Static common:LocalResources.UNameLabel}" LabelStyle="{DynamicResource ContentLabelStyle}"
ImageStyle="{DynamicResource ViewContentControlStyle}">
<ctl:ETextBox x:Name="UserName" HorizontalAlignment="Left" Style="{StaticResource {x:Type TextBox}}"
LostFocus="Textbox_OnLostFocus"
Text="{Binding Path=UserName, UpdateSourceTrigger=PropertyChanged, NotifyOnValidationError=True, ValidatesOnDataErrors=True}">
</ctl:ETextBox>
</ctl:NewLabel>
</StackPanel>
<StackPanel Grid.Row="9" Grid.Column="2" Style="{StaticResource ViewContentStyle}" Visibility="{Binding SelectedAuthenticationType, Converter={StaticResource AuthToVisibility}}">
<StackPanel Orientation="Horizontal" KeyboardNavigation.TabNavigation="None">
<Label Style="{DynamicResource ContentLabelStyle}" Content="{x:Static common:LocalResources.UPasswordLabel}"/>
<AdornerDecorator>
<PwdBox x:Name="Password"
HorizontalAlignment="Left"
LostFocus="Textbox_OnLostFocus" PasswordChar="*"
</PwdBox>
</AdornerDecorator>
</StackPanel>
I have 3 files where almost the same code is reused. I think there is a way to get rid of this by using a common custom control. However, I dont see much examples as to how it can be done. Any leads would be great.
Add a new UserControl to your project and move the common XAML to this one.
You could then create an instance of this UserControl (replace "UserControl1" with the actual name of your UserControl) in any other view:
<!--insert the shared markup here: -->
<local:UserControl1 />
I'm new to WPF. I have a combobox which when choosing a value three other fields (AbbrBlock, MultiBrandSupplier, IgnoreNoCompetition) update along to show the correct relevant values according to the data source. No problem with this.
Issue arises when I try to add to the combobox a custom value, although the combobox shows all values correctly, the other fields don't change when changing the combobox's value.
Here's the working code (without the additional custom combobox value - stripped to the key pieces):
<Window.Resources>
<local:OrdersDataSet x:Key="ordersDataSet" />
<CollectionViewSource x:Key="caSuppliersViewSource" Source="{Binding CaSuppliers, Source={StaticResource ordersDataSet}}"/>
</Window.Resources>
...
<StackPanel DataContext="{StaticResource caSuppliersViewSource}">
<ComboBox Name="SupplierDropdown" DisplayMemberPath="SupplierName"
ItemsSource="{Binding Source={StaticResource ResourceKey=caSuppliersViewSource}}"/>
<TextBlock Name="AbbrBlock" VerticalAlignment="Center" Text="{Binding Abbr}"/>
<CheckBox Name="MultiBrandSupplier" IsChecked="{Binding MultiBrand}"/>
<CheckBox Name="IgnoreNoCompetition" IsChecked="{Binding IgnoreNoCompetition}"/>
</StackPanel>
Here's the code with the added custom value which shows correctly but the other fields don't update when changing the combobox value:
<Window.Resources>
<local:OrdersDataSet x:Key="ordersDataSet" />
<CollectionViewSource x:Key="caSuppliersViewSource" Source="{Binding CaSuppliers, Source={StaticResource ordersDataSet}}"/>
</Window.Resources>
...
<StackPanel DataContext="{StaticResource caSuppliersViewSource}">
<StackPanel.Resources>
<CompositeCollection x:Key="myCompositeCollection">
<CollectionContainer Collection="{Binding Source={StaticResource ResourceKey=caSuppliersViewSource}}" />
<ComboBoxItem Content="Add New..." />
</CompositeCollection>
</StackPanel.Resources>
<ComboBox Name="SupplierDropdown" DisplayMemberPath="SupplierName"
ItemsSource="{Binding Source={StaticResource myCompositeCollection}}"/>
<TextBlock Name="AbbrBlock" VerticalAlignment="Center" Text="{Binding Abbr}"/>
<CheckBox Name="MultiBrandSupplier" IsChecked="{Binding MultiBrand}"/>
<CheckBox Name="IgnoreNoCompetition" IsChecked="{Binding IgnoreNoCompetition}"/>
</StackPanel>
What am I missing here?
Looks like the ComboBox was updating caSuppliersViewSource's View.CurrentItem property (I think) to match its SelectedItem in your first snippet. In the second, the CollectionViewSource is buried inside a CompositeCollection so that doesn't happen any more. However, the ComboBox is still selecting an item, and you can just bind to that using ElementName. No need for setting the DataContext on the StackPanel with this version.
<StackPanel>
<StackPanel.Resources>
<CompositeCollection x:Key="myCompositeCollection">
<CollectionContainer Collection="{Binding Source={StaticResource ResourceKey=caSuppliersViewSource}}" />
<ComboBoxItem Content="Add New..." />
</CompositeCollection>
</StackPanel.Resources>
<ComboBox
Name="SupplierDropdown"
DisplayMemberPath="SupplierName"
ItemsSource="{Binding Source={StaticResource myCompositeCollection}}"
/>
<TextBlock
Name="AbbrBlock"
VerticalAlignment="Center"
Text="{Binding SelectedItem.Abbr, ElementName=SupplierDropdown}"
/>
<CheckBox
Name="MultiBrandSupplier"
IsChecked="{Binding SelectedItem.MultiBrand, ElementName=SupplierDropdown}"
/>
<CheckBox
Name="IgnoreNoCompetition"
IsChecked="{Binding SelectedItem.IgnoreNoCompetition, ElementName=SupplierDropdown}"
/>
</StackPanel>
You could also give eyour viewmodel a SelectedDBItem property of the same type as whatever caSuppliersViewSource contains, and bind ComboBox.SelectedItem to that. Then you could do this:
<TextBlock
Name="AbbrBlock"
VerticalAlignment="Center"
Text="{Binding SelectedDBItem}"
/>
But that's six dozen of one, half of another, or something -- unless you want to do something else with SelectedDBItem in your viewmodel, then it's handy.
I have a WPF usercontrol with a combobox & textbox. I want the textbox to hold the value of the selected item in the combobox and it works fine if I use SelectedValue in the binding path. However if I try to use the Title column of the combobox (SelectedValue.Title) the value of the textbox is overwritten but nothing is displayed. Can anyone tell me what I am doing wrong? My code sample is below. I am a newbie at this so please be kind :)
<ComboBox x:Name="ComboProject" Grid.Column="4" Grid.Row="0" TabIndex="14"
ItemsSource="{Binding Source={StaticResource Projects}, XPath=./Project}"
SelectedValuePath="#Item"
Tag="Project Number"
TextSearch.TextPath="#Item">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text= "{Binding XPath= #Item}" Width="90" />
<TextBlock Text= "{Binding XPath= #Title}" Width="220" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBox x:Name="loaded" Text="{Binding Path=SelectedValue.Title, NotifyOnSourceUpdated=True, ElementName=ComboProject}" Grid.Row="2" Grid.Column="4" Tag="Project Title" TabIndex="15"/>
You set SelectedValuePath="#Item", so that's what SelectedValue has right now. Try setting it to Title and binding directly to SelectedValue:
<ComboBox x:Name="ComboProject"
ItemsSource="{Binding Source={StaticResource Projects}, XPath=./Project}"
SelectedValuePath="#Title">
<ComboBox.ItemTemplate>
...
</ComboBox.ItemTemplate>
</ComboBox>
<TextBox Text="{Binding SelectedValue, ElementName=ComboProject}" />
I removed some other code for clarity of example.
EDIT :
Ok, if you want to use SelectedValue for other purposes we can bind TextBox to SelectedItem instead. If the Title is an attribute of a selected XML node, then we can access it like this:
<TextBox Text="{Binding SelectedItem.Attributes[Title].Value, Mode=OneWay, ElementName=ComboProject}" />
I have a ComboBox whose ItemsSource is binding to a collection and the SelectedItem is binding to the properties of my VieModel. Let's call the binding properties AvailableOptions and TargetOption in ViewModel. And type of collection item and TargetOption is called MyOption. I have such requirements but I don't know how to fulfill them all:
It should be OK for the binding TargetOption to have NULL as value
I want to set a DataTemplate for the target type in TargetOption collection to be displayed in the ComboBox
If possible, I want use different DataTemplate for MyOption when then are in the drop-down of ComboBox and when one item is selected. Because my UserControl has limited space so it should be compact when item is selected and during the selection it should provide more information
As I said, I don't know how to do all of them. At first I have the XAML like this:
<ComboBox SelectedItem="{Binding SelectedOption} ItemsSource="{Binding AvailableOptions}" >
<ComboBox.ItemTemplateSelector>
<MyNameSpace:ComboBoxItemTemplateSelector ItemTemplate="{StaticResource OptionDetailTemplate}" SelectedItemTemplate="{StaticResource OptionSimpleTemplate}" />
</ComboBox.ItemTemplateSelector>
</ComboBox>
With a customized ItemTemplateSelector. I am able to do the requirement 2) and 3). My OptionDetailTemplate looks like this:
<DataTemplate x:Key="OptionDetailTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ShortName}" />
<TextBlock Text=" | " />
<TextBlock Text="{Binding Code}" />
</StackPanel>
</DataTemplate>
and OptionSimpleTemplate looks like this:
<DataTemplate x:Key="OptionSimpleTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ShortName}" />
<TextBlock Text=" | " />
<TextBlock Text="{Binding Code}" />
<TextBlock Text=" | " />
<TextBlock Text="{Binding Number}" />
</StackPanel>
</DataTemplate>
But now the problem is requirement 1). When the user select one option from the drop down list of the ComboBox, he can't put it as NULL back which should be allowed. This is because AvailableOption doesn't have a NULL object
I see that if I set IsEditable to True for the ComboBox, and set TextSearch.TextPath to Code, it allows the text quick search/assign and also allows to have a NULL value when the search text is totally deleted. But now when I ever select one, it only displays Code (the OptionTemplate does not have any effect any more because now it displays the selected item in a TextBox). This is not good since only Code is not enough for the user to tell what Option it is. But since I have multiple properties in MyOption class, how can I define the DataTemplate for the TextBox and also define the search routine?
I have to be honest that I didn't fully understand your first requirement and its ramifications. however, I am really just answering to let you know that you don't even need to use a DataTemplateSelector to select between your two DataTemplates. If you do not set the x:Key value on them, then they will be applied to the relevant items implicitly:
<DataTemplate DataType="{x:Type YourXamlNamespacePrefix:TargetOption}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ShortName}" />
<TextBlock Text=" | " />
<TextBlock Text="{Binding Code}" />
</StackPanel>
</DataTemplate>
...
<DataTemplate DataType="{x:Type YourXamlNamespacePrefix:MyOption}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ShortName}" />
<TextBlock Text=" | " />
<TextBlock Text="{Binding Code}" />
<TextBlock Text=" | " />
<TextBlock Text="{Binding Number}" />
</StackPanel>
</DataTemplate>
Furthermore, you could do all this data binding with just a single TextBlock if you use a MultiDataTrigger:
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}|{1}">
<Binding Path="ShortName" />
<Binding Path="Code" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
Perhaps if you try clarifying your remaining problem (in your question), I might understand?
How to exclude TextBlock from tabbing sequence in SILVERLIGHT Grid XAML. I know for TextBox, we use IsTabStop false OR TabIndex -1, but same property is not avaiable for TextBlock
I have 4 controls, 1 and 4 are TextBox (editable) and 2 and 3 are TextBlock (non editable). When I tab, all the 4 are included in the tabbing sequence.
I want to exclude 2,3 (Textblocks) from tabbing. Means, If I tab from TextBox 1, focus should move directly to TextBox 4. please help.
Loaded="UserControl_Loaded">
<DataTemplate x:Key="CellEditClientAllocations" >
<TextBox Text="{Binding ClientAllocations, Mode=TwoWay}"
Style="{StaticResource GridCellTextBoxStyle}"
x:Name="tbxClientAllocations"
Loaded="TextBox_Loaded"
TextChanged="tbxClientAllocations_TextChanged"
KeyDown="tbxClientAllocations_KeyDown"
LostFocus="tbxClientAllocations_LostFocus"
GotFocus="tbxClientAllocations_GotFocus"/>
</DataTemplate>
<DataTemplate x:Key="CellAccountId">
<TextBlock Text="{Binding AccountId, Converter={StaticResource anc}}" Style="{StaticResource GridCellTextBlockStyle}" /> </DataTemplate>
<DataTemplate x:Key="CellEditAccountId">
<TextBox Text="{Binding AccountId, Converter={StaticResource anc}, Mode=TwoWay}" x:Name="tbxAccountId" LostFocus="TbxAccountIdLostFocus" TextChanged="TbxAccountIdTextChanged" GotFocus="tbxAccountId_GotFocus"/>
</DataTemplate><DataTemplate x:Key="CellAccountName"> <StackPanel>
<TextBlock VerticalAlignment="Center" Text="{Binding AccountName, Mode=TwoWay}" Foreground="{Binding IsAccountValid, Converter={StaticResource cc}}" kStyle="{StaticResource GridCellTextBlockStyle}" Name="Account" MouseRightButtonUp="" > </TextBlock> </StackPanel> </DataTemplate>
<DataTemplate x:Key="CellLotInstructions"> <StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding LotInstructions}" Style="{StaticResource GridCellTextBlockStyle}"/>
<HyperlinkButton Content="Edit" Style="{StaticResource HyperlinkButtonStyleUnderline}" IsEnabled="{Binding LotInstructionsEnabled}" Name="Lotinstructons" HorizontalContentAlignment="Center" MouseLeftButtonDown="LotinstructonsMouseLeftButtonDown" VerticalContentAlignment="Center" Click="ViewSpecifyLots_Click" Visibility="{Binding LotInstructionsEdit}" /> </StackPanel> </DataTemplate>
Try setting attached property KeyboardNavigation.TabNavigation to None.
<TextBlock KeyboardNavigation.TabNavigation="None"/>
Set Focusable="False" for the textblock
I think you may need to work on the DataGrid Column rather than the Cell content (your TextBlock) it is the Cell that is Focussed not the TextBlock.
You could assign an event handler to the CellEnter Event (accessible from the definition of the original column) and then set the DataGrids selected cell selected property to false. Not the neatest solution but it should work.
Alternatively you could create a behaviour to do this....
Hope this helps!