How to Find a Control that is inside DataTemplate & assign Value in WPF?

二次信任 提交于 2019-12-02 16:06:14

问题


I have a DataTemplate which is binded to Grid Group Header Section. There are four TextBlock in DataTemplate from one of TextBlock contains the Grid Header Column Value. Now, I want to Split this TextBlock Value into three and assign this value to other three TextBlock from Code Behind. Is it Possible?

<DataTemplate x:Key="descriptionHeader">
            <!--<dxg:GroupGridRowContent>
                <TextBlock Background="Yellow" Text="{Binding DisplayText}" ></TextBlock>
            </dxg:GroupGridRowContent>-->

            <Border BorderBrush="Black"  BorderThickness="1" Width="1300">
                <StackPanel Orientation="Vertical" Margin="2">
                    <TextBlock Name="txtdescription" Text="{Binding DisplayText}" Width="200" HorizontalAlignment="Left" ></TextBlock>
                    <StackPanel Orientation="Horizontal" Margin="2" Height="80">

                        <Image Source=".\Images\description_img.png"  Stretch="None" FlowDirection="LeftToRight" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="1"/>
                        <StackPanel Orientation="Vertical" Margin="2">
                            <TextBlock Name="txtdesc1" Margin="2" FlowDirection="LeftToRight" Text="{Binding Path=GlassType,RelativeSource={RelativeSource Self}}"  TextWrapping="Wrap"  />
                            <TextBlock Name="txtdesc2" Margin="2" FlowDirection="LeftToRight" Text="{Binding Path=(dxg:RowData.RowData).GroupSummaryData[3].Text, RelativeSource={RelativeSource Self}}"  TextWrapping="Wrap"  />
                            <TextBlock Name="txtdesc3" Margin="2" FlowDirection="LeftToRight" Text="{Binding Path=(dxg:RowData.RowData).GroupSummaryData[4].Text, RelativeSource={RelativeSource Self}}"   TextWrapping="Wrap"  />
                        </StackPanel>
                    </StackPanel>
            </StackPanel>
            </Border>
        </DataTemplate>
    </Window.Resources>

  <dxg:GridControl Name="grdInfill"  Height="700" VerticalAlignment="Top" >
        <dxg:GridControl.Columns>
            <dxg:GridColumn FieldName="GlassType" AllowEditing="False"   />
            <dxg:GridColumn FieldName="GlassDescription" GroupValueTemplate="{StaticResource descriptionHeader}">
                <!--GroupValueTemplate="{StaticResource descriptionHeader}"-->
                <!--Header="GlassDescription" DisplayMemberBinding="{Binding Path=RowData.Row.GlassDescription, Mode=TwoWay}"-->
            </dxg:GridColumn>
            <dxg:GridColumn FieldName="GlassType" AllowEditing="False" />
            <dxg:GridColumn Name="qty" Header="Quantity" AllowEditing="False" DisplayMemberBinding="{Binding Path=RowData.Row.Quantity, Mode=TwoWay}" /> <!--FieldName="Quantity"-->
            <dxg:GridColumn FieldName="Width" AllowEditing="False" Header="Length"/>
            <dxg:GridColumn FieldName="Height" AllowEditing="False"/>
            <dxg:GridColumn FieldName="Elevation" AllowEditing="False"/>
            <dxg:GridColumn FieldName="Mark" AllowEditing="False"/>
            <dxg:GridColumn FieldName="GlassTag" AllowEditing="False"/>
            <dxg:GridColumn FieldName="WallLocation" AllowEditing="False"/>
            <dxg:GridColumn FieldName="SquareFoot" AllowEditing="False"/>
            <dxg:GridColumn FieldName="Weight" AllowEditing="False"/>
            <dxg:GridColumn FieldName="UnitCost" AllowEditing="False"/>
            <dxg:GridColumn FieldName="TotalCost" AllowEditing="False"/>
            <dxg:GridColumn FieldName="FuelSurcharge" AllowEditing="False"/>

        </dxg:GridControl.Columns>
        <dxg:GridControl.View>
            <dxg:TableView ShowTotalSummary="True" AutoWidth="True" DetailHeaderContent="True"  ShowIndicator="False" ShowGroupPanel="False"><!--GroupRowTemplate="{StaticResource descriptionHeader}"-->
            </dxg:TableView>
        </dxg:GridControl.View>
    </dxg:GridControl>




protected void GetAllInfills()
        {
            List<Infill> infillList = new List<Infill>();
            infillList=BLL.GetAllInfills();
            if (infillList != null)
            {
                grdInfill.ItemsSource = infillList;

                grdInfill.GroupBy(grdInfill.Columns["GlassType"], ColumnSortOrder.Ascending);
                grdInfill.GroupBy(grdInfill.Columns["GlassDescription"], ColumnSortOrder.Ascending);

                grdInfill.AutoExpandAllGroups = true;

            }
        }

From Above marukup i want to access the TextBlock Control i.e 'txtdescription' which contains the group header section value of Grid Column 'GlassDescription' now i want to split this value int to three value i.e txtdescription.Split('*') and assign values to other three textblock i.e txtdesc1,txtdesc2,txtdesc3 that are in DataTemplate from code behind.


回答1:


Since you requested a sample, I am providing a sample using ListBox.
XAML

<Window.Resources>
</Window.Resources>

<Grid>
    <ListBox x:Name="lstBox" ItemsSource="{Binding ListBoxItems}">
        <ListBox.ItemTemplate>
            <DataTemplate >
                <Border BorderBrush="Black"  BorderThickness="1" Width="1300" DataContext="{Binding DataContext, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}">
                    <StackPanel Orientation="Vertical" Margin="2">
                        <TextBlock Name="txtdescription" Text="{Binding DisplayText, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" Width="200" HorizontalAlignment="Left" ></TextBlock>
                        <StackPanel Orientation="Horizontal" Margin="2" Height="80">

                            <StackPanel Orientation="Vertical" Margin="2">
                                <TextBlock Name="txtdesc1" Text="{Binding Path=TextBlock0}"/>
                                <TextBlock Name="txtdesc2" Text="{Binding Path=TextBlock1}"/>
                                <TextBlock Name="txtdesc3" Text="{Binding Path=TextBlock2}"/>
                            </StackPanel>
                        </StackPanel>
                    </StackPanel>
                </Border>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

CodeBehind

public partial class DataTemplateWindow : Window {
    public DataTemplateWindow() {

        DisplayText = "Some*Text*With*Separators";
        string [] splittedTextArray = DisplayText.Split('*');
        TextBlock0 = splittedTextArray[0];
        TextBlock1 = splittedTextArray[1];
        TextBlock2 = splittedTextArray[2];

        ListBoxItems = new List<string>();
        ListBoxItems.Add("Item 1");

        InitializeComponent();
        this.DataContext = this;
    }

    public string DisplayText { get; set; }

    public string TextBlock0 { get; set; }
    public string TextBlock1 { get; set; }
    public string TextBlock2 { get; set; }

    public List<string> ListBoxItems { get; set; }
}

EDIT in response to additional information

In WPF you can use Element Binding which allows you to access any property of a given element. Since you want to access txtdescription textblock's text property, you will have to use the Element Binding. But you wan't to split that into three TextBlocks. So you will need a converter.

Use the code below for element binding

<StackPanel Orientation="Vertical" Margin="2">
    <TextBlock Name="txtdesc1" Text="{Binding ElementName=txtdescription, Path=Text, Converter={StaticResource splitter}, ConverterParameter=0 }"/>
    <TextBlock Name="txtdesc2" Text="{Binding ElementName=txtdescription, Path=Text, Converter={StaticResource splitter}, ConverterParameter=1 }"/>
    <TextBlock Name="txtdesc3" Text="{Binding ElementName=txtdescription, Path=Text, Converter={StaticResource splitter}, ConverterParameter=2 }"/>
</StackPanel>

And here is the converter code

public class SplitterConverter : IValueConverter {

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
        string combinedString = value as string;
        if (!string.IsNullOrEmpty(combinedString)) {
            string [] splitArray = combinedString.Split('*');
            int postion = int.Parse(parameter as string);
            switch (postion) {
                case 0:
                    return splitArray[0];
                case 1:
                    return splitArray[1];
                case 2:
                    return splitArray[2];
                default: 
                    return null;
            }
        }
        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
        throw new NotImplementedException();
    }
}

Finally Include Converter Namespace in xaml

<Window x:Class="WpfApplication1.DataTemplateWindow"
    xmlns:cv="clr-yourconverterclassnamespace"
    ...
    >
<Window.Resources>
     <cv:SplitterConverter x:Key="splitter" />
</Window.Resources>
....
</Window>


来源:https://stackoverflow.com/questions/16727854/how-to-find-a-control-that-is-inside-datatemplate-assign-value-in-wpf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!