1

I want to show two horizontal lines within a graphic. The Position of the Lines is depending on some data. Therefor I created a ValueConverter (basically double to int). The Problems is, the lines are always shown in the same position.

I have to following XAML:

    <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:CGM_Auswertung"
            xmlns:chartingToolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit" x:Class="CGM_Auswertung.MainWindow"
            mc:Ignorable="d"
            Title="MainWindow" Height="780" Width="1300" Loaded="Window_Loaded">
        <Window.Resources>
            <local:DoubleToPositionConverter x:Key="DtPConverter"/>
        </Window.Resources>
        <Grid Name="MainGrid">
            <StackPanel Margin="10" Orientation="Vertical">
                <Button Name="OpenFile" Content="Öffnen" Height="30" Margin="550,0" Click="OpenFile_Click"/>
                <Grid x:Name="drawGrid" >
                    <TextBox Height="30" Width="40" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding OptMinimum}"/>
                    <Frame x:Name="drawFrame" HorizontalAlignment="Left" Height="420" Margin="40,10,10,50" VerticalAlignment="Top" Width="1210" BorderBrush="Black" BorderThickness="3">
                        <Frame.Content>
                            <Grid Name="contentGrid" Background="Transparent" >
                                <Line x:Name="MinLine" Stroke="Red" StrokeThickness="2" StrokeDashArray="2,2" X1="0" X2="1200" Y1="{Binding OptMinimum, Converter={StaticResource DtPConverter}}" Y2="{Binding OptMinimum, Converter={StaticResource DtPConverter}}"/>
                                <Line x:Name="MaxLine" Stroke="Red" StrokeThickness="2" StrokeDashArray="2,2" X1="0" X2="1200" Y1="{Binding OptMaximum, Converter={StaticResource DtPConverter}}" Y2="{Binding OptMaximum, Converter={StaticResource DtPConverter}}"/>
                                <Grid Name="vertLineGrid" MouseMove="tempLineGrid_MouseMove" Background="Transparent" HorizontalAlignment="Center" VerticalAlignment="Center" Height="394" Width="1183" MouseUp="ReleaseSelectedItem"/>
                            </Grid>
                        </Frame.Content>
...

this is the converter:

namespace CGM_Auswertung
{
    public class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            PropertyChanged?.Invoke(this, e);
        }
    }

    public class ViewModel : ViewModelBase
    {
        ...

        private double _optMinimum;
        public double OptMinimum
        {
            get { return _optMinimum; }
            set
            {
                _optMinimum = value;
                OnPropertyChanged(new PropertyChangedEventArgs("OptMinimum"));
            }
        }

        private double _optMaximum;
        public double OptMaximum
        {
            get { return _optMaximum; }
            set
            {
                _optMaximum = value;
                OnPropertyChanged(new PropertyChangedEventArgs("OptMaximum"));
            }
        }


    }

    public class DoubleToPositionConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return (int)(Math.Abs(400 - (double)value * 20));
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return (double)(Math.Abs((double)value / 20 - 400 / 20));
        }
    }
}

I also tried this before the converter:

[ValueConversion(typeof(double),typeof(int))]

but it didn't change anything And here is the start of my program:

namespace CGM_Auswertung
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        private List<CGM_Measurement> completeMeasures = new List<CGM_Measurement>();       
        private ViewModel mvm = new ViewModel() { MinimalValue = 0, MaximalValue=0, ActualValue=0};
        private UIElement selectedItem = null;

        public MainWindow()
        {
            mvm.FirstDay = mvm.LastDay = DateTime.Today;
            mvm.OverviewText = "Switch to day view";
            mvm.Visual = Visibility.Visible;
            mvm.VisualInverse = Visibility.Collapsed;
            mvm.OptMinimum = 2.0;
            mvm.OptMaximum = 3.0;

            InitializeComponent();

            MainGrid.DataContext = mvm;

        }

I guess the problem is somewhere in the xaml, because when i set a breakpoint within my converter the convert is never called.

I guess because the conversion is so simple I could use another property within my viewmodel. But since im still learning about WPF I would like to do it with a value converter.

Thanks for your help.

Stewbob
  • 16,759
  • 9
  • 63
  • 107
Thoms
  • 87
  • 8
  • Did you set a breakpoint in the converter to test if it is getting called at all? – Flat Eric Dec 08 '17 at 15:30
  • 2
    Why are you using an `IValueConverter` to make some calculations? A converter is supposed to convert the objects' types, not to participate in your layout/application logic. While there are a lot of SO answers encouraging to misuse the `IValueConverter`s for such tasks, they mostly introduce an ugly workaround for some bad code/design. – dymanoid Dec 08 '17 at 15:30
  • @dymanoid: i know its supposed to convert objects. this is merly a coordinate transformation which basically converts the coordinates of one koordinate space to another. so a conversion in the widest way. do you have another suggestion how to achive this without adding additional properties to the view model? because the same property without conversion is used in textboxes. are there built in soulutions for coordinate transforation that i dont know of? – Thoms Dec 09 '17 at 12:58

1 Answers1

2

Frame doesn't inherit DataContext of parent container (explained in this SO post). So contentGrid is missing source for its bindings. As a result bindings are not resolved and converter is not called. Try replace Frame with ContentControl or just remove it completely

ASh
  • 34,632
  • 9
  • 60
  • 82
  • +1 Also: the `Frame` can be used for displaying web content. If you need that functionality, MSDN recommends that you use `Page` instead. from [MSDN](https://msdn.microsoft.com/en-us/library/system.windows.controls.frame(v=vs.110).aspx#Remarks): "Content can be any type of .NET Framework object and HTML files. In general, however, pages are the preferred the way to package content for navigation (see [Page](https://msdn.microsoft.com/en-us/library/system.windows.controls.page(v=vs.110).aspx) )." – Stewbob Dec 08 '17 at 16:50