可变数据绑定WPF单元格样式-对象内部的对象

时间:2018-12-13 13:20:20

标签: c# wpf xaml data-binding wpfdatagrid

我当前面临的问题是创建一种可以应用于每列但使用不同变量的单元格样式。

目前,我不得不重复样式代码并更改一个变量,如下所示:

XAML:

<DataGridTextColumn Header="CR Implement" Binding="{Binding CRIMPLEMENTATION.End_Date, StringFormat=dd-MM-yyyy}" HeaderStyle="{StaticResource CenterGridHeaderStyle}"  Width= "90" >
                    <DataGridTextColumn.CellStyle >
                        <Style TargetType="{x:Type DataGridCell}">
                            <Setter Property="TextBlock.TextAlignment" Value="Center" />
                            <Setter Property="TextBlock.FontSize" Value="16" />
                            <Setter Property="VerticalContentAlignment" Value="Center"/>
                            <Setter Property="ToolTip" Value="{Binding CRIMPLEMENTATION.StatusInfo}" />
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding CRIMPLEMENTATION.MultiBooking}" Value="True">
                                    <Setter Property="BorderBrush" Value="Black" />
                                    <Setter Property="BorderThickness" Value="1.5" />
                                </DataTrigger>
                                <DataTrigger Binding="{Binding CRIMPLEMENTATION.status}" Value="1">
                                    <Setter Property="Background" Value="LimeGreen" />
                                </DataTrigger>
                                <DataTrigger Binding="{Binding CRIMPLEMENTATION.status}" Value="2">
                                    <Setter Property="Background" Value="Yellow" />
                                </DataTrigger>
                                <DataTrigger Binding="{Binding CRIMPLEMENTATION.status}" Value="3">
                                    <Setter Property="Background" Value="Orange" />
                                </DataTrigger>
                                <MultiDataTrigger>
                                    <MultiDataTrigger.Conditions>
                                        <Condition Binding="{Binding CRIMPLEMENTATION.isLateValue}" Value="1" />
                                        <Condition Binding="{Binding CRIMPLEMENTATION.status}" Value="0" />
                                    </MultiDataTrigger.Conditions>
                                    <Setter Property="Background" Value="Red" />
                                </MultiDataTrigger>
                                <MultiDataTrigger>
                                    <MultiDataTrigger.Conditions>
                                        <Condition Binding="{Binding CRIMPLEMENTATION.isLateValue}" Value="0" />
                                        <Condition Binding="{Binding CRIMPLEMENTATION.status}" Value="0" />
                                    </MultiDataTrigger.Conditions>
                                    <Setter Property="Background" Value="White" />
                                </MultiDataTrigger>
                            </Style.Triggers>
                        </Style>
                    </DataGridTextColumn.CellStyle>

此XAML当前针对每个单独的列重复30次。

每个单元格样式和数据网格文本列中唯一的可变性是:变量名称。

以下代码段旨在更清晰地概述如何设置类。

C#类:

  public class Job
{
    public string JobDescription { get; set; }

    public int JobID { get; set; }

    public Dictionary<String, List<Booking>> MyBookings = new Dictionary<String, List<Booking>>();

    public Dictionary<String, List<String>> Emails = new Dictionary<string, List<string>>();
    public Booking MilestoneCRBriefAvailable { get; set; }
    public Booking MilestoneCRQuoted { get; set; }
    public Booking MilestoneCRQuoteApproved { get; set; }
}

C#类

  public class Booking
{

    public int isLateValue { get; set; } = 0;
    public string StatusInfo { get; set; }
    public string Counter { get; set; }
    public int BKGID { get; set; }
    public int JobID { get; set; }
    public int UserID { get; set; }
    public int CMPID { get; set; }
    public DateTime? Start_Date { get; set; }
    public DateTime? End_Date { get; set; }
    public string Notes { get; set; }
    public int status { get; set; }
}

理想的情况是更改示例中的硬编码变量

CRIMPLEMENTATION.end_date 

收件人

****.end_date

任何建议都会有很大帮助。

1 个答案:

答案 0 :(得分:1)

您不能绑定数据触发器的值。

暂时,我想不出如何用转换器优雅地做到这一点。您可以传入该列的索引,但它确实很脆弱。

我有时如何做“尴尬”的事情是使用xamlreader.parse动态构建列。我建立一个字符串,它是基础列标记。然后,我将其更改(在字符串中)并将其解析为一列,然后将其添加到数据网格中。

与其将您的代码拆开,不如向我展示一些我可以粘贴的代码。

我想要一个枚举来驱动我具有用户编辑值的列(和行)。这实际上是强制红色与强制蓝色,以及红色步兵与红色步兵,红色步兵与蓝色光步兵的攻击值等等。

因此,有两个攻击矩阵和一个用户控件使用了两次。 我建立这些列:

public partial class AttackMatrixView : UserControl
{
    public Sides AttackingSide = Sides.Red;
    public Sides DefendingSide = Sides.Blue;
    public AttackMatrixView()
    {
        Resources.Add("AttackerSide", AttackingSide);
        Resources.Add("DefenderSide", DefendingSide);
        InitializeComponent();
        XElement col = GetXElement(@"pack://application:,,,/Views/AttackFactors/attackFactorColumn.txt");
        foreach (UnitTypes ut in  Enum.GetValues(typeof(UnitTypes)).Cast<UnitTypes>().Where(x=>x.ThisFights()==true).Select(x=>x).ToList())
        {
            XElement el = new XElement(col);
            string colString = el.ToString()
                .Replace("^^^Index^^^", ((int)ut).ToString())
                .Replace("^^^EnumString^^^", ut.ToString())
                .Replace("^^^EnumDescription^^^", ut.ToDescriptionString());
            ParserContext context = new ParserContext();
            context.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
            context.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
            DataGridTextColumn tc = (DataGridTextColumn)XamlReader.Parse(colString, context);
            dg.Columns.Add(tc);
        };

    }
    private XElement GetXElement(string uri)
    {
        XDocument xmlDoc = new XDocument();
        var xmltxt = Application.GetContentStream(new Uri(uri));
        string elfull = new StreamReader(xmltxt.Stream).ReadToEnd();
        xmlDoc = XDocument.Parse(elfull);
        return xmlDoc.Root;
    }
}

使用txt文件:

<?xml version="1.0" encoding="utf-8" ?>
<DataGridTextColumn Binding="{Binding Factor[^^^Index^^^], Mode=TwoWay,      UpdateSourceTrigger=PropertyChanged}" Width="*"  
xmlns:ui="clr-namespace:UILib;assembly=UILib"
xmlns:local="clr-namespace:ScenarioEditor"
xmlns:model="clr-namespace:ModelLib;assembly=ModelLib"
>
 <DataGridTextColumn.HeaderTemplate>
     <DataTemplate>
         <ui:IconParent Height="20" Width="30" 
                 ui:IconParent.IPType="{x:Static model:UnitTypes.^^^EnumString^^^}"
                 ui:Icon.UnitType="{x:Static model:UnitTypes.^^^EnumString^^^}"
                 ui:Icon.Side="{Binding DataContext.DefenderSide
                    , RelativeSource={RelativeSource AncestorType=UserControl}}"
                >
            <ui:IconParent.ToolTip>
                <ToolTip>
                    ^^^EnumDescription^^^
                </ToolTip>
            </ui:IconParent.ToolTip>
                <ui:UnitIcon Margin="2"/>
        </ui:IconParent>
    </DataTemplate>
</DataGridTextColumn.HeaderTemplate>

您可能会有类似的东西,并操纵datatrigger的值,绑定的内容等。

为清楚起见-具有两个攻击矩阵实例的最终视图: enter image description here