【问题标题】:WPF Why are my Line objects not changing position?WPF 为什么我的 Line 对象没有改变位置?
【发布时间】:2017-12-08 15:23:46
【问题描述】:

我想在一个图形中显示两条水平线。线的位置取决于一些数据。 为此,我创建了一个 ValueConverter(基本上是 int 的两倍)。问题是,线条总是显示在相同的位置。

我必须关注 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>
...

这是转换器:

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

我在转换器之前也试过这个:

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

但它并没有改变任何东西 这是我的程序的开始:

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;

        }

我猜问题出在 xaml 中,因为当我在转换器中设置断点时,不会调用转换。

我猜是因为转换非常简单,我可以在我的视图模型中使用另一个属性。但是由于我还在学习 WPF,所以我想用一个值转换器来做。

感谢您的帮助。

【问题讨论】:

  • 你是否在转换器中设置了一个断点来测试它是否被调用?
  • 为什么要使用IValueConverter 进行一些计算?转换器应该转换对象的类型,而不是参与您的布局/应用程序逻辑。虽然有很多 SO 答案鼓励滥用 IValueConverters 来完成此类任务,但它们大多为一些糟糕的代码/设计引入了一种丑陋的解决方法。
  • @dymanoid:我知道它应该转换对象。这只是一种坐标变换,它基本上将一个坐标空间的坐标转换为另一个坐标空间。所以以最广泛的方式进行转换。您是否有其他建议如何在不向视图模型添加其他属性的情况下实现这一目标?因为文本框中使用了相同的属性而无需转换。是否有我不知道的坐标转换的内置解决方案?

标签: c# wpf xaml ivalueconverter valueconverter


【解决方案1】:

Frame 不继承父容器的 DataContext(在this SO post 中解释)。所以contentGrid 缺少绑定源。结果绑定没有被解析并且转换器没有被调用。尝试用 ContentControl 替换 Frame 或完全删除它

【讨论】:

  • +1 另外:Frame 可用于显示 Web 内容。如果您需要该功能,MSDN 建议您改用Page。来自MSDN:“内容可以是任何类型的 .NET Framework 对象和 HTML 文件。但是,通常,页面是打包导航内容的首选方式(请参阅Page)。”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-12
  • 2018-11-21
  • 1970-01-01
  • 1970-01-01
  • 2016-01-03
  • 1970-01-01
相关资源
最近更新 更多