数据网格中的矩形,绑定矩形的宽度值

3

我试图将矩形的宽度属性绑定到一个变量上,这样每添加一条记录到数据网格中,矩形的宽度就不同了(类似图表)。我甚至无法使用x:Name访问该矩形。

XAML:

<DataGrid.Columns>
   <DataGridTextColumn Binding="{Binding Path=Data}" Header="Data"  ></DataGridTextColumn>
   <DataGridTextColumn Binding="{Binding Path=Pamaina}" Header="Pamaina"></DataGridTextColumn>
   <DataGridTextColumn Binding="{Binding Path=TyrimoVieta}" Header="Tyrimo vieta"></DataGridTextColumn>
   <DataGridTextColumn Binding="{Binding Path=Koncentracija}" Header="Koncentacija"></DataGridTextColumn>
   <DataGridTemplateColumn Header="Rect">
      <DataGridTemplateColumn.CellTemplate>
         <DataTemplate>
            <StackPanel x:Name="assTR">
               <Rectangle Width="{Binding ilgis}" Height="10" Fill="Green" />
            </StackPanel>
         </DataTemplate>
      </DataGridTemplateColumn.CellTemplate>
   </DataGridTemplateColumn>
</DataGrid.Columns>

C#

List<DatagridItems> datagridItems = new List<DatagridItems>();

public class DatagridItems
{
   public string Data { get; set; }
   public string Pamaina { get; set; }
   public string TyrimoVieta { get; set; }
   public string Koncentracija { get; set; }
}

public List<DatagridItems> LoadCollectionData(string data, string pamaina, string tyrimovieta, string koncentracija)
{
   Datagrid_1.Items.Refresh(); //du refresh kad atsinaujintu kolekcija
   datagridItems.Add(new DatagridItems()
   {
      Data = data,
      Pamaina = pamaina,
      TyrimoVieta = tyrimovieta,
      Koncentracija = koncentracija,
   });
   Datagrid_1.Items.Refresh();

   return datagridItems;
}

调用以填充数据网格

Datagrid_1.ItemsSource = LoadCollectionData(datosFormatas, row["pamaina"].ToString(), tyrimoVieta_isFunkcijos, koncentracija);

我其实不知道这样做是否能实现我的要求。下面是我想要实现的图片。我想要在“Koncentracija”中的值设置绿色矩形的宽度。这能行吗?我只能绘制固定宽度的矩形。

感谢任何帮助。我想要实现的图片

3个回答

1
我希望将“Koncentracija”中的值设置为绿色矩形的宽度。这能做到吗?
是可以的。
基本上,您想要将一个字符串类型的变量与表示矩形宽度的变量绑定在一起。如何实现?
通常,宽度用数字表示;)
因此,最简单的解决方案是 - 您需要更改Koncentracija属性的数据类型为int或decimal,正如@thatguy所指出的那样。但为了保持简单,不使用转换器 - 您必须提供一种机制来通知视图该属性已更改。
最简单的方法是实现INotifyPropertyChanged接口,并在setter中以属性名称触发propertychanged事件,如下所示:
public class DataGridViewItem : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged(string property)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
    }

    public string Data { get; set; }
    public string Pamaina { get; set; }
    public string TyrimoVieta { get; set; }

    private int koncentracija;
    public int Koncentracija
    {
        get { return koncentracija; }
        set
        {
            koncentracija = value;
            RaisePropertyChanged(nameof(Koncentracija));
        }
    }
}

我制作了一个简单的视图来表示向DataGrid添加元素,通过点击按钮改变矩形的宽度。以下是该视图代码:

<Window x:Class="WpfApp1.MainWindow"
    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:WpfApp1"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
<Grid>
    <DataGrid Name="MyDataGrid" HorizontalAlignment="Left" Height="150" Margin="44,74,0,0" VerticalAlignment="Top" Width="171"/>
    <Rectangle Name="MyRectangle" Fill="Green" HorizontalAlignment="Left" Width="{Binding Koncentracija}" Height="47" Margin="350,91,0,0" Stroke="Black" VerticalAlignment="Top" />
    <Button Name="AddItemBtn" Content="AddToDataGrid" Margin="63,281,615.6,0" VerticalAlignment="Top" Width="115" Height="53" FontSize="16" Click="AddItemBtn_Click"/>
</Grid>

现在,在您的视图代码后端(例如我的示例中的“MainWindow.xaml.cs”),有一个简单的逻辑,您可以根据自己的问题进行调整。在这里,我将Koncentracija值增加了30,但您当然可以通过从所需对象获取数据来实现这一点。
代码如下:
 public partial class MainWindow : Window
{
    DataGridViewItem dataItem = new DataGridViewItem();
    List<Person> people = new List<Person>() { new Person { Name = "Mark", Age = 12 }, new Person { Name = "Chris", Age = 22 } };

    public MainWindow()
    {
        InitializeComponent();
        MyDataGrid.ItemsSource = people;
        DataContext = dataItem;
    }

    private void AddItemBtn_Click(object sender, RoutedEventArgs e)
    {
        people.Add(new Person() { Name = "Tom", Age = 27 });
        dataItem.Koncentracija += 30;
        MyDataGrid.Items.Refresh();
    }
}

这是一个图片,展示了它的外观https://ibb.co/B4FCD6S 希望有所帮助 :)
*编辑:我建议您在创建WPF应用程序时熟悉MVVM模式,因为它会对您有很大帮助。这里有一个教程:https://www.tutorialspoint.com/mvvm/index.htm

感谢您提供详细信息。我最终在我的类中创建了一个宽度(decimal),原因是浓度值(Koncentracija)太小,无法在图表中使用。宽度 = 浓度 * 4。必须深入研究MVVM模式。干杯。链接 - user3524910

0
你需要创建一个自定义的DataGridTemplateColumn。你可以在DataTemplate中放置任何你想要的内容。
这样做是可行的:

MainWindow.xaml

<DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False" IsReadOnly="True">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Name" Binding="{Binding Name}">
        </DataGridTextColumn>
        <DataGridTemplateColumn Header="Width">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Rectangle Width="{Binding Width}" Height="10" Fill="Blue" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

MainWindowVM.cs

using GalaSoft.MvvmLight;
using System.Collections.Generic;

namespace WpfApp1
{
    public class MainWindowVM : ObservableObject
    {
        private List<Item> _Items;
        public List<Item> Items
        {
            get { return _Items; }
            set
            {
                if (value != _Items)
                {
                    _Items = value;
                    RaisePropertyChanged();
                }
            }
        }
        public MainWindowVM()
        {
            Items = new List<Item>()
            {
                new Item() {Name = "one", Width = 30.5 },
                new Item() { Name = "two", Width = 10.2 }
            };

        }
    }

    public class Item : ObservableObject
    {
        private string _Name;
        public string Name
        {
            get { return _Name; }
            set
            {
                if (value != _Name)
                {
                    _Name = value;
                    RaisePropertyChanged();
                }
            }
        }

        private double _Width;
        public double Width
        {
            get { return _Width; }
            set
            {
                if (value != _Width)
                {
                    _Width = value;
                    RaisePropertyChanged();
                }
            }
        }
    }
}

结果:

Datagrid with two columns. Second column has variable width rectangles


0
理想情况下,Koncentracija 属性应该是 double 类型而不是 string,但为此您需要创建一个自定义数据列,提供对数字类型的支持和验证以防止无效值,或者使用附加行为或类型转换。您可以在 this post 中找到解决方案。
这也将允许您将 Koncentracija 属性简单地绑定到 RectangleWidth 上,并且它将在您的示例中工作。您可以使用 HorizontalAlignment 将条形图左对齐。
<Rectangle HorizontalAlignment="Left" Width="{Binding Koncentracija}" Height="10" Fill="Green" />

如果您想保留代码不变,您可以为 Koncentracija 创建一个单向转换器。

public class StringToDoubleConverter : IValueConverter
{
   public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
   {
      double.TryParse((string)value, out var result);
      return result;
   }

   public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
   {
      throw new InvalidOperationException();
   }
}

您可以为 DataGrid 创建一个此转换器的实例,并将 Width 属性绑定到使用该转换器自动将 string 转换为 doubleKoncentracija
<DataGrid ...>
   <DataGrid.Resources>
      <local:StringToDoubleConverter x:Key="StringToDoubleConverter"/>
   </DataGrid.Resources>
   <DataGrid.Columns>
      <DataGridTextColumn Binding="{Binding Path=Data}" Header="Data"  ></DataGridTextColumn>
      <DataGridTextColumn Binding="{Binding Path=Pamaina}" Header="Pamaina"></DataGridTextColumn>
      <DataGridTextColumn Binding="{Binding Path=TyrimoVieta}" Header="Tyrimo vieta"></DataGridTextColumn>
      <DataGridTextColumn Binding="{Binding Path=Koncentracija}" Header="Koncentacija"></DataGridTextColumn>
      <DataGridTemplateColumn Header="Rect">
         <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
               <StackPanel x:Name="assTR">
                  <Rectangle HorizontalAlignment="Left" Width="{Binding Koncentracija, Converter={StaticResource StringToDoubleConverter}}" Height="10" Fill="Green" />
               </StackPanel>
            </DataTemplate>
         </DataGridTemplateColumn.CellTemplate>
      </DataGridTemplateColumn>
   </DataGrid.Columns>
</DataGrid>

作为一般性的提示,你应该在你的视图模型中实现 INotifyPropertyChanged,否则在运行时对属性所做的更改将不会反映在用户界面上。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接