【问题标题】:WPF how can i bind multiple properties in datagridrowWPF如何在datagridrow中绑定多个属性
【发布时间】:2020-10-14 11:47:20
【问题描述】:

我已经在 DataGridRow(不是 DataGridTextcolumn)中绑定了静态属性。怎么绑定?

我已经在普通网格中手动绑定了一个静态属性。代码如下所示(但现在如何在 DataGridRow-Wise 中绑定属性)。

<Window x:Class="Data_Grid_Row_HeaderBindingTest.GridTest"
        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:Data_Grid_Row_HeaderBindingTest"
        mc:Ignorable="d"
        Title="GridTest" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <TextBlock Text="ArgumentName" Grid.Row="0" Grid.Column="0" FontSize="25" TextAlignment="Center" Margin="10"/>
        <TextBlock Text="ArgumentValue" Grid.Row="0" Grid.Column="1" FontSize="25" TextAlignment="Center" Margin="10"/>
        <TextBlock Text="IA" Grid.Row="1" Grid.Column="0" FontSize="25" TextAlignment="Center" Margin="10"/>
        <TextBlock Text="IB" Grid.Row="2" Grid.Column="0" FontSize="25" TextAlignment="Center" Margin="10"/>
        <TextBlock Text="IC" Grid.Row="3" Grid.Column="0" FontSize="25" TextAlignment="Center" Margin="10"/>
        <TextBlock Text="ID" Grid.Row="4" Grid.Column="0" FontSize="25" TextAlignment="Center" Margin="10"/>
        <TextBlock Text="IE" Grid.Row="5" Grid.Column="0" FontSize="25" TextAlignment="Center" Margin="10"/>
        <TextBlock Text="IF" Grid.Row="6" Grid.Column="0" FontSize="25" TextAlignment="Center" Margin="10"/>
        <TextBlock Text="IG" Grid.Row="7" Grid.Column="0" FontSize="25" TextAlignment="Center" Margin="10"/>
        <TextBox Text="{Binding Path=(local:Model.IA),Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Grid.Row="1" Grid.Column="1" Width="360" Height="40"/>
        <TextBox Text="{Binding Path=(local:Model.IB),Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Grid.Row="2" Grid.Column="1" Width="360" Height="40"/>
        <TextBox Text="{Binding Path=(local:Model.IC),Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Grid.Row="3" Grid.Column="1" Width="360" Height="40"/>
        <TextBox Text="{Binding Path=(local:Model.ID),Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Grid.Row="4" Grid.Column="1" Width="360" Height="40"/>
        <TextBox Text="{Binding Path=(local:Model.IE),Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Grid.Row="5" Grid.Column="1" Width="360" Height="40"/>
        <TextBox Text="{Binding Path=(local:Model.IF),Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Grid.Row="6" Grid.Column="1" Width="360" Height="40"/>
        <TextBox Text="{Binding Path=(local:Model.IG),Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Grid.Row="7" Grid.Column="1" Width="360" Height="40"/>
        <!--<DataGrid x:Name="MyGrid" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Argument Name" Binding="{Binding ArgumentName}"></DataGridTextColumn>
                <DataGridTextColumn Header="Argument Value" Binding="{Binding Path=(local:Model.IA),Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                                    ></DataGridTextColumn>
            </DataGrid.Columns>
            --><!--<DataGrid.RowHeaderTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
                                  AncestorType={x:Type DataGridRow}},
                                  Path=Item.Row.Header}"/>
                </DataTemplate>
            </DataGrid.RowHeaderTemplate>--><!--

            <DataGrid.RowHeaderStyle>
                <Style TargetType="DataGridRowHeader">
                    <Setter Property="Content" Value="{Binding Path=(local:Model.Name)}"/>
                </Style>
            </DataGrid.RowHeaderStyle>
        </DataGrid>-->
    </Grid>
</Window>

模型类

using System;
using System.Collections.Generic;
using System.Text;

namespace Data_Grid_Row_HeaderBindingTest
{
    public class Model
    {
        private static int iA;
        private static int iB;
        private static int iC;
        private static int iD;
        private static int iE;
        private static int iF;
        private static int iG;
        private static string name;

        public static int IA
        {
            get
            {
                return iA;
            }
            set
            {
                iA = value;
                // Raise a change event
                OnFilterStringChanged(EventArgs.Empty);
            }
        }
        public static int IB
        {
            get
            {
                return iB;
            }
            set
            {
                iB = value;
                // Raise a change event
                OnFilterStringChanged(EventArgs.Empty);
            }
        }

        public static int IC
        {
            get
            {
                return iC;
            }
            set
            {
                iC = value;
                // Raise a change event
                OnFilterStringChanged(EventArgs.Empty);
            }
        }
        public static int ID
        {
            get
            {
                return iD;
            }
            set
            {
                iD = value;
                // Raise a change event
                OnFilterStringChanged(EventArgs.Empty);
            }
        }
        public static int IE
        {
            get
            {
                return iE;
            }
            set
            {
                iE = value;
                // Raise a change event
                OnFilterStringChanged(EventArgs.Empty);
            }
        }
        public static int IF
        {
            get
            {
                return iF;
            }
            set
            {
                iF = value;
                // Raise a change event
                OnFilterStringChanged(EventArgs.Empty);
            }
        }
        public static int IG
        {
            get
            {
                return iG;
            }
            set
            {
                iG = value;
                // Raise a change event
                OnFilterStringChanged(EventArgs.Empty);
            }
        }
        public static string Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
                // Raise a change event
                OnFilterStringChanged(EventArgs.Empty);
            }
        }
        // Declare a static event representing changes to your static property
        public static event EventHandler FilterStringChanged;

        // Raise the change event through this static method
        protected static void OnFilterStringChanged(EventArgs e)
        {
            EventHandler handler = FilterStringChanged;

            if (handler != null)
            {
                handler(null, e);
            }
        }

        static Model()
        {
            // Set up an empty event handler
            FilterStringChanged += (sender, e) => { return; };
        }
    }
}

附图:

但现在相同的属性绑定到DataGrid。如何绑定?

【问题讨论】:

  • 很难理解你想说什么。另外,请不要将属性命名为 IA、IB、IC ...
  • 这似乎是一个非常熟悉的问题。转换为行视图模型的列表或 observablecollection。那应该有 propertyname 和 propertyvalue 属性。加上一个propertyinfo。通过迭代属性并使用每个属性的属性信息来创建该集合。您可以使用 propertyinfo 作为名称并获取/设置值。当他们点击提交更改时,您可以迭代列表并使用 prooertyinfo 将值设置回源属性。
  • 这能回答你的问题吗? Twoway binding datagrid wpf xaml
  • 不确定你想要什么。它没有写清楚。首先,使用“当前输出”和“预期输出”更新问题。您可以在 Excel 中创建预期的输出。

标签: wpf data-binding datagrid datagridviewrow


【解决方案1】:

我想你要找的是MultiBinding:

<Window x:Class="MultiBinding.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:MultiBinding"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:NameList x:Key="NameListData"/>
        <local:NameConverter x:Key="MyNameConverter"/>

        <DataTemplate x:Key="NameItemTemplate">
            <TextBlock>
                <TextBlock.Text>
                    <MultiBinding Converter="{StaticResource MyNameConverter}">
                        <Binding Path="FirstName"/>
                        <Binding Path="LastName"/>
                    </MultiBinding>
                </TextBlock.Text>
            </TextBlock>
        </DataTemplate>

        <Style TargetType="{x:Type TextBlock}">
            <Setter Property="Width" Value="120"/>
            <Setter Property="Background" Value="Silver"/>
            <Setter Property="HorizontalAlignment" Value="Center"/>
        </Style>
    </Window.Resources>
    <StackPanel>
        <TextBlock FontSize="18" FontWeight="Bold" Margin="10"
                 Background="White" Width="Auto">MultiBinding Sample</TextBlock>

        <ListBox Width="200"
               ItemsSource="{Binding Source={StaticResource NameListData}}"
               ItemTemplate="{StaticResource NameItemTemplate}"
               IsSynchronizedWithCurrentItem="True"/>


        <TextBlock Padding="0,20,0,0" FontSize="11" Background="White">Normal Format:</TextBlock>
        <TextBlock Name="textBox1" DataContext="{StaticResource NameListData}">
            <TextBlock.Text>
                <MultiBinding Converter="{StaticResource MyNameConverter}"
                  ConverterParameter="FormatNormal">
                    <Binding Path="FirstName"/>
                    <Binding Path="LastName"/>
                </MultiBinding>
            </TextBlock.Text>
        </TextBlock>

        <TextBlock Padding="0,20,0,0" FontSize="11" Background="White">Last Name First Format:</TextBlock>
        <TextBlock Name="textBox2" DataContext="{StaticResource NameListData}">
            <TextBlock.Text>
                <MultiBinding Converter="{StaticResource MyNameConverter}"
                      ConverterParameter="FormatLastFirst">
                    <Binding Path="FirstName"/>
                    <Binding Path="LastName"/>
                </MultiBinding>
            </TextBlock.Text>
        </TextBlock>
    </StackPanel>
</Window>

这里是NameConverter

// // Copyright (c) Microsoft. All rights reserved.
// // Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Globalization;
using System.Windows.Data;

namespace MultiBinding
{
    public class NameConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            string name;

            switch ((string) parameter)
            {
                case "FormatLastFirst":
                    name = values[1] + ", " + values[0];
                    break;
                default:
                    name = values[0] + " " + values[1];
                    break;
            }

            return name;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            var splitValues = ((string) value).Split(' ');
            return splitValues;
        }
    }
}

NameList:

// // Copyright (c) Microsoft. All rights reserved.
// // Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Collections.ObjectModel;

namespace MultiBinding
{
    public class NameList : ObservableCollection<PersonName>
    {
        public NameList()
        {
            Add(new PersonName("Willa", "Cather"));
            Add(new PersonName("Isak", "Dinesen"));
            Add(new PersonName("Victor", "Hugo"));
            Add(new PersonName("Jules", "Verne"));
        }
    }
}

PersonName:

// // Copyright (c) Microsoft. All rights reserved.
// // Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace MultiBinding
{
    public class PersonName
    {
        public PersonName(string first, string last)
        {
            FirstName = first;
            LastName = last;
        }

        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
}

这里是完整源代码的链接,进入WPFSamples.sln中的Samples->Data Binding->MultiBinding项目即可:

https://drive.google.com/drive/folders/0BxL9JBEAEaAUcjlxNWdzU3h6bjA?resourcekey=0-N-piwEgxrfTw4CT-4cnEqA&usp=sharing

详情请看:

https://docs.microsoft.com/en-us/previous-versions/ms771633(v=vs.100)?redirectedfrom=MSDN

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-05
    • 1970-01-01
    • 2012-02-08
    • 1970-01-01
    • 2014-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多