0

好的,所以我不知道这是否可能,但是?我正在尝试填充 DataGrid(确切地说是 Telerik RadGridView)并希望动态确定编辑控件。我正在尝试创建一个网格来显示正在导入应用程序的数据并显示三列(属性名称、入站数据和当前数据库数据)。基于我的对象类中的属性,“属性名称”列需要在其前面放置一个 CheckBox。这与其他列一起有条件地附加一个按钮,以便可以进行查找(一个 TextBox 或 TextBlock 将位于按钮前面以显示当前值)。我希望这能解释我正在尝试做的事情。下面是我想出的 XAML。

哦,这将进入 WPF MVVM C#​​ 应用程序。

感谢您的任何帮助,您可以提供。

<UserControl x:Class="PulseHL7Importer.Views.DetailView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
         xmlns:p="clr-namespace:PulseHL7Importer.Properties"
         xmlns:fw="clr-namespace:PulseHL7Importer.Framework"
         xmlns:vm="clr-namespace:PulseHL7Importer.ViewModels"
         mc:Ignorable="d" 
         d:DesignHeight="200" d:DesignWidth="961">
<UserControl.Resources>
    <telerik:BooleanToVisibilityConverter x:Key="BooleanVisibilityConverter" />
    <DataTemplate x:Key="AddCheckBox">
        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding HasCheckBox}" Value="True" />
        </DataTemplate.Triggers>
        <CheckBox IsChecked="{Binding IsChecked}" Margin="2,0,5,0" VerticalAlignment="Center" HorizontalAlignment="Center" />
    </DataTemplate>
    <DataTemplate x:Key="AddTextBlock">
        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding IsReadOnly}" Value="True" />
        </DataTemplate.Triggers>
        <TextBlock Text="{Binding Value}" />
    </DataTemplate>
    <DataTemplate x:Key="AddTextBox">
        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding IsReadOnly}" Value="False" />
        </DataTemplate.Triggers>
        <TextBox Text="{Binding Value}" />
    </DataTemplate>
    <DataTemplate x:Key="AddButton">
        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding HasLookup}" Value="True" />
        </DataTemplate.Triggers>
        <Button Content="..." Width="{Binding RelativeSource={RelativeSource Self}, Path=ActualHeight}"
                VerticalAlignment="Center" HorizontalAlignment="Center"/>
    </DataTemplate>
    <DataTemplate x:Key="ConditionalTemplate">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <ContentPresenter Grid.Column="0" Content="{Binding}" ContentTemplate="{StaticResource AddCheckBox}" />
            <ContentPresenter Grid.Column="1" Content="{Binding}" ContentTemplate="{StaticResource AddTextBlock}" />
            <ContentPresenter Grid.Column="1" Content="{Binding}" ContentTemplate="{StaticResource AddTextBox}" />
            <ContentPresenter Grid.Column="2" Content="{Binding}" ContentTemplate="{StaticResource AddButton}" />
        </Grid>
    </DataTemplate>
</UserControl.Resources>
<Grid d:DataContext="{d:DesignInstance vm:DetailViewModel}">
    <telerik:RadDockPanel Width="Auto">
        <!-- Toolbar -->
        <telerik:RadDockPanel telerik:RadDockPanel.Dock="Top">
            <telerik:RadToolBar OverflowButtonVisibility="Collapsed" />
        </telerik:RadDockPanel>

        <!-- Warnings and Errors -->
        <telerik:RadDockPanel telerik:RadDockPanel.Dock="Bottom">
            <telerik:GroupBox Header="Warnings and Errors"
                              telerik:Theming.Theme="{Binding Source={x:Static p:Settings.Default}, Path=SelectedTheme}">
                <TextBox Height="60" IsReadOnly="True"
                         VerticalScrollBarVisibility="Auto"
                         Background="FloralWhite" />
            </telerik:GroupBox>
        </telerik:RadDockPanel>

        <!-- Grid Area -->
        <telerik:RadDockPanel Width="Auto">
            <telerik:RadGridView Name="DetailGridView" Width="Auto" AutoGenerateColumns="False" RowIndicatorVisibility="Collapsed"
                                 CanUserDeleteRows="False" CanUserInsertRows="False" CanUserReorderColumns="False" 
                                 CanUserSortColumns="False" IsFilteringAllowed="False" ColumnWidth="*"
                                 ShowGroupPanel="False" ItemsSource="{Binding Path=Properties}" >
                <telerik:RadGridView.Columns>
                    <telerik:GridViewDataColumn Header="Name" DataMemberBinding="{Binding Path=Value}">
                        <telerik:GridViewDataColumn.CellTemplate>
                            <DataTemplate>
                                <ContentPresenter ContentTemplate="{StaticResource ConditionalTemplate}" Content="{Binding Path=Properties}" />
                            </DataTemplate>
                        </telerik:GridViewDataColumn.CellTemplate>
                        <telerik:GridViewDataColumn.CellEditTemplate>
                            <DataTemplate>
                                <ContentPresenter ContentTemplate="{StaticResource ConditionalTemplate}" Content="{Binding Path=Properties}" />
                            </DataTemplate>
                        </telerik:GridViewDataColumn.CellEditTemplate>
                    </telerik:GridViewDataColumn>
                    <telerik:GridViewDataColumn Header="Client Data" DataMemberBinding="{Binding Path=ClientData.Value}">
                        <telerik:GridViewDataColumn.CellEditTemplate>
                            <DataTemplate>
                                <ContentPresenter ContentTemplate="{StaticResource ConditionalTemplate}" Content="{Binding Path=ClientData}" />
                            </DataTemplate>
                        </telerik:GridViewDataColumn.CellEditTemplate>
                    </telerik:GridViewDataColumn>
                    <telerik:GridViewDataColumn Header="Pulse Data" DataMemberBinding="{Binding Path=PulseData.Value}">
                        <telerik:GridViewDataColumn.CellEditTemplate>
                            <DataTemplate>
                                <ContentPresenter ContentTemplate="{StaticResource ConditionalTemplate}" Content="{Binding Path=PulseData}" />
                            </DataTemplate>
                        </telerik:GridViewDataColumn.CellEditTemplate>
                    </telerik:GridViewDataColumn>
                </telerik:RadGridView.Columns>
            </telerik:RadGridView>
        </telerik:RadDockPanel>
    </telerik:RadDockPanel>
</Grid>

4

3 回答 3

0

通常ContentPresenters获取相应的隐式模板,因此您只需要将其中Content的一个绑定到您想要模板化的属性或 DataContext 并且应该对其进行模板化。

(不确定这是否适用于您的问题,因为我不太明白您想说什么)

于 2012-06-27T22:35:03.200 回答
0

好的,我已经设法通过一些技巧解决了这个问题。我现在在 CellEditTemplateSelector 中动态创建 DataTemplate。这使我可以检查所有属性并为适当的单元格添加控件和绑定。

这是基本的 XAML 网格:

                <telerik:RadGridView Name="DetailGridView" Width="Auto" AutoGenerateColumns="False" RowIndicatorVisibility="Collapsed"
                                 CanUserDeleteRows="False" CanUserInsertRows="False" CanUserReorderColumns="False" 
                                 CanUserSortColumns="False" IsFilteringAllowed="False" ColumnWidth="*"
                                 ShowGroupPanel="False" ItemsSource="{Binding Path=Properties}">
                <telerik:RadGridView.Columns>
                    <telerik:GridViewDataColumn Header="Name" IsReadOnlyBinding="{Binding Path=IsReadOnly}"
                                                DataMemberBinding="{Binding Path=Value}"
                                                CellTemplateSelector="{StaticResource CellTemplateSelector}"
                                                CellEditTemplateSelector="{StaticResource CellEditTemplateSelector}">
                        <telerik:GridViewDataColumn.CellStyle>
                            <Style>
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding Path=IsReadOnly}" Value="True">
                                        <Setter Property="Canvas.Background" Value="LightGoldenrodYellow" />
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding Path=IsGroupItem}" Value="True">
                                        <Setter Property="Canvas.Background"  Value="LightGray" />
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding Path=IsRequired}" Value="True">
                                        <Setter Property="TextElement.Foreground" Value="Red" />
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </telerik:GridViewDataColumn.CellStyle>
                    </telerik:GridViewDataColumn>
                    <telerik:GridViewMaskedTextBoxColumn Header="Client Data"
                                                DataMemberBinding="{Binding Path=ClientData.Value}"
                                                CellEditTemplateSelector="{StaticResource CellEditTemplateSelector}">
                        <telerik:GridViewMaskedTextBoxColumn.CellStyle>
                            <Style>
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding Path=ClientData.IsReadOnly}" Value="True">
                                        <Setter Property="Canvas.Background" Value="LightGoldenrodYellow" />
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding Path=IsGroupItem}" Value="True">
                                        <Setter Property="Canvas.Background"  Value="LightGray" />
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </telerik:GridViewMaskedTextBoxColumn.CellStyle>
                    </telerik:GridViewMaskedTextBoxColumn>
                    <telerik:GridViewDataColumn Header="Pulse Data"
                                                DataMemberBinding="{Binding Path=PulseData.Value}" 
                                                CellEditTemplateSelector="{StaticResource CellEditTemplateSelector}">
                        <telerik:GridViewDataColumn.CellStyle>
                            <Style>
                                <Style.Triggers>
                                   <DataTrigger Binding="{Binding Path=PulseData.IsReadOnly}" Value="True">
                                        <Setter Property="Canvas.Background" Value="LightGoldenrodYellow" />
                                   </DataTrigger>
                                   <DataTrigger Binding="{Binding Path=IsGroupItem}" Value="True">
                                        <Setter Property="Canvas.Background"  Value="LightGray" />
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </telerik:GridViewDataColumn.CellStyle>
                    </telerik:GridViewDataColumn>
                </telerik:RadGridView.Columns>
            </telerik:RadGridView>

这是 CellEditTemplateSelector:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using Telerik.Windows.Controls.GridView;
using System.Windows.Markup;
using System.Windows.Media;

namespace PulseHL7Importer.Framework
{
public class CellEditTemplateSelector : DataTemplateSelector
{
    public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
    {
        FrameworkElement element = (FrameworkElement)container;

        if (element != null && item != null && item is Property)
        {
            GridViewCell cell = (GridViewCell)container;
            Property property = (Property)item;
            Column column = null;
            StringBuilder grid = new StringBuilder();
            BrushConverter converter = new BrushConverter();

            #region Control Header

            grid.Append("<DataTemplate");
            grid.Append(" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"");
            grid.Append(" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"");
            grid.Append(" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"");
            grid.Append(" xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"");
            grid.Append(" xmlns:telerik=\"http://schemas.telerik.com/2008/xaml/presentation\"");
            grid.Append(" mc:Ignorable=\"d\"");
            grid.Append(">");

            #endregion  //Control Header

            switch (cell.Column.Header.ToString().Replace(" ", "").ToUpper())
            {
                case "NAME":
                    grid.Append("<StackPanel Orientation=\"Horizontal\"");
                    if (property.IsGroupItem)
                        grid.Append(" Background=\"LightGray\">");
                    else
                        grid.Append(">");
                    if (property.HasCheckBox)
                    {
                        grid.Append("<Grid Width=\"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=StackPanel, AncestorLevel=1}," +
                            " Path=ActualWidth}\">");
                        grid.Append("<Grid.ColumnDefinitions>");
                        grid.Append("<ColumnDefinition Width=\"Auto\" />");
                        grid.Append("<ColumnDefinition Width=\"*\" />");
                        grid.Append("</Grid.ColumnDefinitions>");
                    }
                    if (property.HasCheckBox)
                        grid.Append("<CheckBox Grid.Column=\"0\" IsChecked=\"{Binding Path=IsChecked}\" Margin=\"3,2,3,0\" />");
                    if (property.IsReadOnly)
                        grid.AppendFormat("<TextBlock{0} Text=\"{{Binding Path=Value}}\"", property.HasCheckBox ? " Grid.Column=\"1\"" : "");
                    else
                        grid.AppendFormat("<TextBox{0} Text=\"{{Binding Path=Value}}\"", property.HasCheckBox ? " Grid.Column=\"1\"" : "");
                    if (!property.HasCheckBox)
                    {
                        grid.Append(" Margin=\"15,0,0,0\" ");
                        grid.Append(" Width=\"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=StackPanel, AncestorLevel=1}," +
                            " Path=ActualWidth}\"");
                    }
                    if(!property.IsReadOnly)
                        grid.Append(" BorderBrush=\"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=StackPanel, AncestorLevel=1}," +
                            " Path=BorderBrush}\"");
                    grid.Append(" Background=\"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=StackPanel, AncestorLevel=1}," +
                        " Path=Background}\" />");
                    if (property.HasCheckBox)
                        grid.Append("</Grid>");
                    grid.Append("</StackPanel>");
                    break;
                case "CLIENTDATA":
                    column = property.ClientData;

                    grid.Append(this.BuildColumn(property, "ClientData", column));
                    break;
                case "PULSEDATA":
                    column = property.PulseData;

                    grid.Append(this.BuildColumn(property, "PulseData", column));
                    break;
            }

            #region Control Footer

            grid.Append("</DataTemplate>");

            #endregion

            if (!string.IsNullOrWhiteSpace(grid.ToString()))
            {
                return (DataTemplate)XamlReader.Parse(grid.ToString());
            }
        }

        return base.SelectTemplate(item, container);
    }

    string BuildColumn(Property property, string columnName, Column column)
    {
        StringBuilder grid = new StringBuilder();

        try
        {
            grid.Append("<StackPanel Orientation=\"Horizontal\"");
            if (property.IsGroupItem)
                grid.Append(" Background=\"LightGray\">");
            else if (column.IsReadOnly)
                grid.Append(" Background=\"LightGoldenrodYellow\">");
            else
                grid.Append(">");
            if (column.Options != null && column.Options.Count > 0)
            {
                grid.Append("<telerik:RadComboBox SelectedValue=\"{Binding Path=ClientData.Value}\"" +
                    " ItemsSource=\"{Binding Path=" + columnName + ".Options}\"" +
                    " IsReadOnly=\"{Binding Path=" + columnName + ".IsReadOnly}\"" +
                    " Width=\"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=StackPanel, AncestorLevel=1}," +
                    " Path=ActualWidth}\" />");
            }
            else
            {
                grid.Append("<Grid Width=\"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=StackPanel, AncestorLevel=1}," +
                    " Path=ActualWidth}\">");
                grid.Append("<Grid.ColumnDefinitions>");
                if (column.HasCheckBox)
                    grid.Append("<ColumnDefinition width=\"Auto\" />");
                grid.Append("<ColumnDefinition Width=\"*\" />");
                if (column.HasButton)
                    grid.Append("<ColumnDefinition Width=\"21\" />");
                grid.Append("</Grid.ColumnDefinitions>");
                if (column.HasCheckBox)
                    grid.Append("<CheckBox Grid.Column=\"0\"" +
                        " IsChecked=\"{Binding Path=" + columnName + ".IsChecked}\" Margin=\"3,2,3,0\" />");
                if (column.IsReadOnly)
                {
                    grid.AppendFormat("<TextBlock{0} Text=\"{{Binding Path=" + columnName + ".Value}}\"",
                        column.HasCheckBox ? " Grid.Column=\"1\"" : " Grid.Column=\"0\"");
                    if (property.IsGroupItem)
                        grid.Append(" Margin=\"4,3,3,0\"");
                    else
                        grid.Append(" Margin=\"4,0,0,0\"");
                }
                else if (!string.IsNullOrWhiteSpace(column.Mask))
                {
                    grid.AppendFormat("<telerik:RadMaskedTextBox{0} Value=\"{{Binding Path=" + columnName + ".Value}}\"" +
                        " Mask=\"{{Binding Path=" + columnName + ".Mask}}\"",
                        column.HasCheckBox ? " Grid.Column=\"1\"" : " Grid.Column=\"0\"");
                }
                else
                    grid.AppendFormat("<TextBox{0} Text=\"{{Binding Path=" + columnName + ".Value}}\"",
                        column.HasCheckBox ? " Grid.Column=\"1\"" : " Grid.Column=\"0\"");
                if (!property.IsReadOnly)
                    grid.Append(" BorderBrush=\"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=StackPanel, AncestorLevel=1}," +
                        " Path=BorderBrush}\"");
                grid.Append(" Background=\"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=StackPanel, AncestorLevel=1}," +
                    " Path=Background}\" />");
                if (column.HasButton)
                    grid.AppendFormat("<Button Grid.Column=\"{0}\" Content=\"...\" />",
                        column.HasCheckBox ? "2" : "1");
                grid.Append("</Grid>");
            }
            grid.Append("</StackPanel>");

            return grid.ToString();
        }
        catch (Exception ex)
        {
            throw ex;
        }
        finally
        {
            grid.Clear();
        }

        return string.Empty;
    }
}
}
于 2012-07-06T14:46:03.480 回答
0

您可以将 DataTemplate 的 DataType 属性设置为不同视图模型使用的不同类。

如果同一个视图模型类必须根据内部值有条件地返回不同的模板,您可以在 App.xaml 中声明您的模板

<DataTemplate x:Key="AddCheckBox">
     ...
</DataTemplate>

然后通过使用在视图模型中引用它

public DataTemplate ConditionalTemplate
    {
        get
        {
            if (this.ConditionMet)
                return Application.Current.Resources["AddCheckBox"] as DataTemplate;
            else
                return Application.Current.Resources["DifferentTemplate"] as DataTemplate;
        }
    }

希望这可以帮助

于 2012-06-27T22:46:53.530 回答