Telerik Forums
UI for WPF Forum
2 answers
215 views

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

Martin Ivanov
Telerik team
 answered on 28 Apr 2020
2 answers
292 views

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

Tran
Top achievements
Rank 1
 answered on 28 Apr 2020
2 answers
113 views

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>

 

Kathy
Top achievements
Rank 1
Veteran
 answered on 27 Apr 2020
4 answers
312 views
Hi, I'm a new developer in WPF.

I'm looking a way to validate a page of Wizard control when the "next" button is clicked. 
Basically I have a wizard where the first step check a connection with a SQL Database. This check is made from ViewModel. I need that when the Next is pressed the ViewModel do the check and if return "true" the wizard go to next step.

How I can do this?

I know how to call a command of ViewModel from Wizard but how I can tell "go ahead"?

Thanks.
enrico
Top achievements
Rank 1
Veteran
 answered on 27 Apr 2020
1 answer
107 views

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

Yoan
Telerik team
 answered on 27 Apr 2020
2 answers
274 views

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,

Brian
Top achievements
Rank 1
Veteran
 answered on 24 Apr 2020
2 answers
363 views

How to make the Rad NavigationView control translucent, as shown in the WPF demo app, any idea?

 

Thank you for your attention

Electrónica GOIA
Top achievements
Rank 2
 answered on 24 Apr 2020
2 answers
197 views

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="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: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,

 

Brian
Top achievements
Rank 1
Veteran
 answered on 24 Apr 2020
3 answers
278 views

Hello,

 

Can you please let me know how we can hide all worksheets in a workbook except for the active worksheet?

 

Thanks

Martin
Telerik team
 answered on 24 Apr 2020
3 answers
408 views

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);
            }
        }
    }

 

Vicky
Telerik team
 answered on 24 Apr 2020
Narrow your results
Selected tags
Tags
GridView
General Discussions
Chart
RichTextBox
Docking
ScheduleView
ChartView
TreeView
Diagram
Map
ComboBox
TreeListView
Window
RibbonView and RibbonWindow
PropertyGrid
DragAndDrop
TabControl
TileView
Carousel
DataForm
PDFViewer
MaskedInput (Numeric, DateTime, Text, Currency)
AutoCompleteBox
DatePicker
Buttons
ListBox
GanttView
PivotGrid
Spreadsheet
Gauges
NumericUpDown
PanelBar
DateTimePicker
DataFilter
Menu
ContextMenu
TimeLine
Calendar
Installer and Visual Studio Extensions
ImageEditor
BusyIndicator
Expander
Slider
TileList
DataPager
PersistenceFramework
Styling
TimeBar
OutlookBar
TransitionControl
FileDialogs
Book
ToolBar
ColorPicker
TimePicker
MultiColumnComboBox
SyntaxEditor
VirtualGrid
NavigationView (Hamburger Menu)
Wizard
ExpressionEditor
WatermarkTextBox
DesktopAlert
BarCode
SpellChecker
DataServiceDataSource
EntityFrameworkDataSource
RadialMenu
ChartView3D
Data Virtualization
BreadCrumb
LayoutControl
ProgressBar
Sparkline
TabbedWindow
ToolTip
CloudUpload
ColorEditor
TreeMap and PivotMap
EntityFrameworkCoreDataSource (.Net Core)
HeatMap
Chat (Conversational UI)
VirtualizingWrapPanel
Calculator
NotifyIcon
TaskBoard
TimeSpanPicker
BulletGraph
Licensing
WebCam
CardView
DataBar
FilePathPicker
Callout
PasswordBox
SplashScreen
Localization
Rating
Accessibility
CollectionNavigator
AutoSuggestBox
Security
VirtualKeyboard
HighlightTextBlock
TouchManager
StepProgressBar
Badge
OfficeNavigationBar
ExpressionParser
CircularProgressBar
SvgImage
PipsPager
SlideView
AI Coding Assistant
+? more
Top users last month
Miljana
Top achievements
Rank 2
Iron
Iron
Joel
Top achievements
Rank 3
Bronze
Bronze
Bronze
Cynthia
Top achievements
Rank 1
John
Top achievements
Rank 1
Iron
Mozart
Top achievements
Rank 1
Iron
Veteran
Want to show your ninja superpower to fellow developers?
Top users last month
Miljana
Top achievements
Rank 2
Iron
Iron
Joel
Top achievements
Rank 3
Bronze
Bronze
Bronze
Cynthia
Top achievements
Rank 1
John
Top achievements
Rank 1
Iron
Mozart
Top achievements
Rank 1
Iron
Veteran
Want to show your ninja superpower to fellow developers?
Want to show your ninja superpower to fellow developers?