C# DataGrid内的矩形,绑定矩形的宽度值

C# DataGrid内的矩形,绑定矩形的宽度值,c#,wpf,datagrid,C#,Wpf,Datagrid,我正在尝试将矩形宽度属性绑定到一个变量,以便在数据网格中添加每个记录时,矩形的宽度都是不同的(图表样式)。我甚至无法使用x:Name访问此矩形 XAML: 我不知道这是否能满足我的要求。下面是我想要达到的目标。我想要“Koncentracija”中的值来设置绿色矩形的宽度。这能做到吗?我只画了静态宽度的矩形 感谢您的帮助 您需要创建一个自定义。您可以在数据模板中放入任何需要的内容 这项工作: MainWindow.xaml <DataGrid ItemsSource="{Bind

我正在尝试将矩形宽度属性绑定到一个变量,以便在数据网格中添加每个记录时,矩形的宽度都是不同的(图表样式)。我甚至无法使用
x:Name
访问此矩形

XAML:

我不知道这是否能满足我的要求。下面是我想要达到的目标。我想要“Koncentracija”中的值来设置绿色矩形的宽度。这能做到吗?我只画了静态宽度的矩形


感谢您的帮助

您需要创建一个自定义。您可以在
数据模板
中放入任何需要的内容

这项工作:

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>

结果:


理想情况下,
Koncentracija
属性的类型应为
double
,而不是
string
,但为此,您需要创建一个自定义数据列,该列提供对数值类型的支持,并进行验证,以防止无效值、附加的beahvior或类型之间的转换。您可以在中找到解决方案

这还允许您简单地将
Koncentracija
属性绑定到
矩形
宽度
,在您的示例中可以使用。您可以使用
水平对齐
将条形图左对齐

<Rectangle HorizontalAlignment="Left" Width="{Binding Koncentracija}" Height="10" Fill="Green" />
然后,您将为
DataGrid
创建此转换器的实例,并使用转换器将
Width
属性绑定到
Koncentracija
,该转换器自动将
字符串
转换为
double

<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>

一般来说,您应该在视图模型中添加属性,否则在运行时对属性所做的更改将不会反映在用户界面中

我想要“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,但是ofc可以通过从所需对象获取数据来实现

守则:

 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();
    }
}
公共部分类主窗口:窗口
{
DataGridViewItem dataItem=新DataGridViewItem();
列出人=新名单(){newperson{Name=“Mark”,Age=12},newperson{Name=“Chris”,Age=22};
公共主窗口()
{
初始化组件();
MyDataGrid.ItemsSource=人;
DataContext=dataItem;
}
私有void AddItemBtn_单击(对象发送方,路由目标)
{
添加(newperson(){Name=“Tom”,年龄=27});
dataItem.Koncentracija+=30;
MyDataGrid.Items.Refresh();
}
}
这是一张它的样子 希望有帮助:)


*编辑:我建议您在创建WPF应用程序时熟悉MVVM模式,因为它将对您有很大帮助。这里有一个关于这方面的教程:

谢谢您提供详细信息。我最终在我的类中创建了宽度小数,唯一的原因是Koncentracija值太小,无法在图形中使用。宽度=Koncentracija*4。我们必须深入研究这个MVVM模式。干杯
<Rectangle HorizontalAlignment="Left" Width="{Binding Koncentracija}" Height="10" Fill="Green" />
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 ...>
   <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>
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));
        }
    }
}
<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>
 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();
    }
}