I have a CartesianCustomAnnotation on my chart that draws an ellipse. The ellipse must cover the same amount of chart coordinates (millimeters) in X and Y. Since ellipse height and width are pixels, I had to bind them with a MultiConverter that uses the chart's ConvertDataToPoint function to convert to pixels It generally works well.
But if I change Vertical/Horizontal axes Minimum/Maximum values in code-behind (to achieve Equal-Scale effect I asked you about), even though my binding gets invoked and calls ConvertDataToPoint agin, the pixel values returned do NOT reflect the chart new layout. I'll get values representing the old axis min/max values and they'll look terrible with the new scaling
But then, if I do anything at all to force another update of the binding, suddenly, the values returned will look great again. Even if the change does not alter the underlying values in any meaningful way.
It's almost as the chart's layout code needs for a UI update happen on the control before ConvertDataToPoint will start returning numbers appropriate to the new axes min/max values.
Is there any truth to do this? If I change an axis max/min, do I need to do something (force some layout/update or something) before calling ConvertDataToPoint? Or is there some chart/axis property I should be binding to instead of what I'm using (see below)
Note that I've dumped the numbers going into and out of the converter. They're identical inputs, but completely different outputs from ConvertDataToPoint from when I first change the properties vs when I force a manual update.
Here is the converter
public class ChartDataToPixelsConverter : IMultiValueConverter{ public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { if (values == null || values.Length < 2) return DependencyProperty.UnsetValue; if (!(values[0] is RadCartesianChart chart)) // Must have a chart return DependencyProperty.UnsetValue; if (!(values[1] is double length)) // Must have a diameter value in mm return DependencyProperty.UnsetValue; if (!(values[2] is PointElement element)) // Are we returning X pixels or Y pixels? element = PointElement.X; if (element == PointElement.Y) { var p1 = chart.ConvertDataToPoint(new DataTuple(0, length)); var p2 = chart.ConvertDataToPoint(new DataTuple(0, 0)); var result = Math.Abs(p1.Y - p2.Y); Debug.WriteLine($"length {length.MM} => yHeight {result}"); return result; } else { var p1 = chart.ConvertDataToPoint(new DataTuple(length, 0)); var p2 = chart.ConvertDataToPoint(new DataTuple(0, 0)); var result = Math.Abs(p1.X - p2.X); Debug.WriteLine($"length {length.MM} => xWidth {result}"); return result; } } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { return Enumerable.Repeat(Binding.DoNothing, targetTypes?.Length ?? 0).ToArray(); }}Here is the the ContentTemplate where bind the ellipse height and width as I describe. I've only shown the relevant part of the annotation style
<Style x:Key="ProfileCircleStyle"TargetType="{x:Type tk:CartesianCustomAnnotation}"> <!-- The visual representation is a GreenYellow ellipse --> <Setter Property="ContentTemplate"> <Setter.Value> <DataTemplate DataType="{x:Type tk:CartesianCustomAnnotation}"> <Ellipse Fill="GreenYellow" d:DataContext="{d:DesignInstance {x:Type gci:IProfileOutputCircle}}"> <Ellipse.Width> <!-- Converter only uses first 3 Binding elements. Others are supplied merely to trigger re-evaluation when the related properties change. X-axis minimum is always zero --> <MultiBinding Converter="{StaticResource CvtDataToPixels}" Mode="OneWay"> <Binding ElementName="MyChart"/> <!-- RadCartesianChart --> <Binding Path="Diameter" /> <!-- Diameter in mm --> <Binding Source="{x:Static gcenum:PointElement.X}"/> <!-- Return X pixels, not Y --> <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type tk:RadCartesianChart}}" Path="Zoom"/> <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type tk:RadCartesianChart}}" Path="HorizontalAxis.(tk:LinearAxis.Maximum)"/> </MultiBinding> </Ellipse.Width> <Ellipse.Height> <!-- Converter only uses first 3 Binding elements. Last two are supplied merely to trigger re-evaluation when the related properties change --> <MultiBinding Converter="{StaticResource CvtDataToPixels}" Mode="OneWay"> <Binding ElementName="MyChart"/> <Binding Path="Diameter" /> <Binding Source="{x:Static gcenum:PointElement.Y}"/> <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type tk:RadCartesianChart}}" Path="Zoom"/> <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type tk:RadCartesianChart}}" Path="VerticalAxis.(tk:LinearAxis.Minimum)"/> <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type tk:RadCartesianChart}}" Path="VerticalAxis.(tk:LinearAxis.Maximum)"/> </MultiBinding> </Ellipse.Height> </Ellipse> </DataTemplate> </Setter.Value> </Setter></Style>
I've attached 3 images to show you what I see.
1. The first attachment ("Correct-Normal-Scale.png") shows the chart as initially loaded. The Ellipse is skewed horizontally because the chart axes are not equal scale. But I'm using one size for both X and Y
Here is what my converter dumps for this. The ellipse is correctly much wider than tall
length 2.18513189968 => xWidth 516.7183886108953
length 2.18513189968 => yHeight 48.07290179295998
2. The second attachment ("Incorrect-Equal-Scale.png") shows how it looks right after I check my "Equal Scale" checkbox at the bottom. This causes me to manually set the axes min/max values (notice how they've changed). Even though the X axis has changed dramatically, the ellipse remains skewed horizontally. It should be a circle.
Here is what my converter dumps for this change. Note that X hasn't changed much. Y has not changed at all
length 2.18513189968 => xWidth 503.74066305424367
length 2.18513189968 => yHeight 48.07290179295998
3. Finally, I manually move the blue region just a tiny bit. This causes the binding to be reevaluated. The 3rd Attachment ("Correct-Equal-Scale.png") shows how it looks right after. Notice how the ellipse is now a perfect circle as it should have been.
Here is what my converter dumps. Notice how almost exactly the same input length value now produces identical width and height pixel values.
length 2.184046088752083 => xWidth 61.02891091119042
length 2.184046088752083 => yHeight 61.15329048505832

What I'd like to do is to be able to set it so the amount of text displayed in the columns is fixed and when the grid is resized the size of the font changes to keep the text displayed in each row fixed while having the number of rows shown vary as needed.
Using your Binding to 1 Million records Sample to show what I want, I took a screenshot stretched the grid by 50% in height and width to simulate text enlarging
as the window was widened, and then cropped out 5.5 of the 17 rows of data so that the number of rows visible was reduced because the height wasn't changed.
https://i.imgur.com/sctAk9F.png
I am doing something very simple. I am trying to apply a simple style to a DateTimePicker. Basically, if I use the line
CalendarStyle="{StaticResource calendarStyle}", the drop down calendar doesn't show up. If I remove the line, the calendar works as expected. I'm using runtime version v4.0.30319, description is Progress® Telerik® UI for WPF. Here is the xaml:
<Window x:Class="RadDatePicker.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
xmlns:local="clr-namespace:RadDatePicker"
Title="MainWindow" Height="350" Width="935">
<Window.Resources>
<Style x:Key="calendarStyle" TargetType="telerik:RadCalendar">
<Setter Property="AreWeekNumbersVisible" Value="True" />
</Style>
</Window.Resources>
<Grid Height="207">
<Border CornerRadius="6" >
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<telerik:RadDatePicker x:Name="datePicker"
InputMode="DatePicker"
DisplayFormat="Short"
DateTimeWatermarkContent="Enter date"
DateSelectionMode="Day"
CalendarStyle="{StaticResource calendarStyle}" />
</StackPanel>
</Border>
</Grid>
</Window>
Hi,
I'm develpoing a WPF application using GridView. In my scenario, some cells need to be merged Vertically, some cells while, need to be merged Horizontally. But the MergedCellsDirection property can not be set to two orientations at one time. Is any suggestions or mechanism for this problem?
best regards
Yi
I'm trying to implement the custom Drag Drop behavior depicted at this link: https://docs.telerik.com/devtools/wpf/controls/radtaskboard/features/taskboardcolumndragdropbehavior#taskboardcolumndragdropbehavior
However I cannot get the XAML to recognize this item
<telerik:RadTaskBoard.DragDropBehavior>
The error message is 'The member "DragDropBehavior" is not recognized or is not accessible.
Regards,
How to make the Rad NavigationView control translucent, as shown in the WPF demo app, any idea?
Thank you for your attention
Hi,
I'm working on an application that uses the TaskBoard and have encountered an issue when updating the State property of the TaskBoardCardModel. When the State is updated via binding should the card not move to the appropriate column?
To reproduce the issue I've provided the XAML and view model code for your review.
<Window xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" xmlns:local="clr-namespace:TaskBoardIssue" x:Class="TaskBoardIssue.MainWindow" Title="MainWindow" Height="350" Width="525" WindowState="Maximized" > <Window.DataContext> <local:TaskBoardVM/> </Window.DataContext> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="5*"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <StackPanel Grid.Column="1" Orientation="Vertical"> <Button Content="Add New Model" Margin="3" Command="{Binding AddModel}" /> <Button Content="Update State" Margin="3" Command="{Binding UpdateModel}" /> <telerik:RadPropertyGrid Item="{Binding TestModel}" /> </StackPanel> <telerik:RadTaskBoard ItemsSource="{Binding MyTasks}" GroupMemberPath="State" AutoGenerateColumns="True" /> </Grid></Window>
using System;using System.Collections.Generic;using System.Collections.ObjectModel;using System.ComponentModel;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Input;using Telerik.Windows.Controls;using Telerik.Windows.Controls.TaskBoard;namespace TaskBoardIssue{ public class TaskBoardVM : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; ObservableCollection<TaskBoardCardModel> myTasks; public ObservableCollection<TaskBoardCardModel> MyTasks { get; set; } private TaskBoardCardModel testModel; public TaskBoardCardModel TestModel { get { return testModel; } set { if (testModel != null) if (testModel.Equals(value)) return; testModel = value; this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(TestModel))); } } public TaskBoardVM() { TestModel = new TaskBoardCardModel() { Assignee = "Alpha", Title = "Title Text", Description = "Description Text", State = "Backlog"}; MyTasks = new ObservableCollection<TaskBoardCardModel>() { new TaskBoardCardModel(){ Assignee = "Alpha", Title = "Title Text", Description = "Description Text", State = "Backlog"}, new TaskBoardCardModel(){ Assignee = "Alpha", Title = "Title Text", Description = "Description Text", State = "Active"}, new TaskBoardCardModel(){ Assignee = "Alpha", Title = "Title Text", Description = "Description Text", State = "Complete"}, }; AddModel = new DelegateCommand(InsertTestModel, canBeExecuted); UpdateModel = new DelegateCommand(UpdateTestModel, canBeExecuted); this.CanExecuteCommand = true; } public bool CanExecuteCommand { get; set; } public ICommand AddModel { get; set; } public ICommand UpdateModel { get; set; } private bool canBeExecuted(object obj) { return this.CanExecuteCommand; } private void InsertTestModel(object obj) { MyTasks.Add(TestModel); this.PropertyChanged(this, new PropertyChangedEventArgs(nameof(MyTasks))); } private void UpdateTestModel(object arg) { TestModel.State = "Active"; } }}
If you build and run the application, click the 'Add New Model' and you can see the model being added to the appropriate column. However when you click 'Update Model' you can see the State property does update (see Property Grid), but the Task Card does not move to the correct column.
Regards,
Hello,
Can you please let me know how we can hide all worksheets in a workbook except for the active worksheet?
Thanks

Hi,
i'm using RadBusyIndicator to show "sub views" in our applications main window as BusyContent using BusyContentTemplate and it works.
The problem that i'm having is that the content presenter has locally assigned margin value that i haven't succeeded to override.
What i've tried?
1.) Tried to override the margin with implicit style in resources of RadBusyIndicator with no luck (not also preferred method because of all child content presenters get affected)
2.) Wrote a new custom control that derives from RadBusyIndicator and gave it a "NewMargin" dependency property of type Thickness. When the value of "NewMargin" changes i use VisualTreeHelpers to get the content presenter from visual tree and assing the new value to content presenter, but somehow it doesn't work either. The value gets set but the the view doesn't reflect the change.
The derived indicator:
public class AdaBusyIndicator : RadBusyIndicator
{
public static readonly DependencyProperty NewMarginProperty =
DependencyProperty.Register("NewMargin", typeof(Thickness),
typeof(AdaBusyIndicator), new UIPropertyMetadata(new Thickness(), NewMarginPropertyChanged));
private static void NewMarginPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is AdaBusyIndicator abi && VisualTreeHelpers.FindChild<Border>(abi, "Indicator") is Border brd &&
VisualTreeHelpers.FindChild<ContentPresenter>(brd) is ContentPresenter cpres && e.NewValue is Thickness newThickness)
{
Thickness thickness = new Thickness(newThickness.Left, newThickness.Top, newThickness.Right, newThickness.Bottom);
cpres.Margin = thickness;
}
}
public Thickness NewMargin
{
get
{
return (Thickness)GetValue(NewMarginProperty);
}
set
{
SetValue(NewMarginProperty, value);
}
}
}