wpf UserControl,FindChild返回null

时间:2016-05-19 01:58:14

标签: c# wpf xaml

我有一个usercontrol,其中xaml如下所示。请参阅cs文件中的VisualChild行以解决问题。当我尝试找到UserControl时,我保留一个断点,它是null,因此我找不到textblock元素。我的VisualChild在这个地方是相同的代码。 How can I find WPF controls by name or type? 请帮忙。

XAML:

<UserControl Name="NFView" x:Class="AthenaIsolatedFeatures.ProximityAlerts.Views.NotificationView"
             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:local="clr-namespace:AthenaIsolatedFeatures.ProximityAlerts.Views"
             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
             xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.Resources>
        <DataTemplate x:Key="CustomNotificationTemplate">

            <Border Name="border" BorderBrush="Black" BorderThickness="1" MouseLeftButtonDown="Border_MouseLeftButtonDown">
                <!--<i:Interaction.Triggers>
                    <i:EventTrigger EventName="MouseDown">
                        <i:InvokeCommandAction Command="{Binding AlertClickCommand}" CommandParameter="{Binding}"></i:InvokeCommandAction>
                    </i:EventTrigger>
                </i:Interaction.Triggers>-->

                <DockPanel LastChildFill="True">

                    <StackPanel DockPanel.Dock="Top" Grid.Row="0" Background="Red">
                        <TextBlock Text="Proximity Alert" HorizontalAlignment="Left"></TextBlock>
                    </StackPanel>
                    <Grid Name="GRD2" Background="#FFB6C1" DockPanel.Dock="Bottom" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">

                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"></RowDefinition>
                            <!--<RowDefinition Height="Auto"></RowDefinition>-->
                            <RowDefinition Height="Auto"></RowDefinition>
                            <RowDefinition Height="Auto"></RowDefinition>

                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>

                        </Grid.ColumnDefinitions>

                        <Image Source="{Binding Source}" Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Margin="4,-25,0,0" Height="100" Width="65"></Image>

                        <TextBlock Grid.Row="0" Margin="25,5,0,0" Grid.Column="1" Text="{Binding AlertDescription}" FontSize="15" FontWeight="Bold"></TextBlock>
                        <!--<TextBlock Grid.Row="1" Grid.Column="1" Margin="7,1,0,0" Text="{Binding requestId}"></TextBlock>-->
                        <TextBlock Grid.Row="1" Margin="25,-28,0,0" Grid.Column="1" Text="{Binding requestId,StringFormat='Session: {0}'}"></TextBlock>
                        <TextBlock Grid.Row="0" Grid.Column="2" HorizontalAlignment="Right" Margin="39,5,0,0" Text="{Binding alertTimeStamp}"></TextBlock>
                        <TextBlock Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" Margin="25,-30,0,0" Text="{Binding AlertText}"></TextBlock>
                        <TextBlock Name="tblAlertId" Grid.Row="2" Grid.Column="1" Text="{Binding alertId}" Visibility="Collapsed"></TextBlock>
                    </Grid>
                </DockPanel>
            </Border>
        </DataTemplate>
    </UserControl.Resources>
    <Grid>

    </Grid>
</UserControl>

我背后的代码

 public partial class NotificationView : UserControl
    {
        public int alertId { get; set; }

        public NotificationView()
        {
            InitializeComponent();
        }

        private void Border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {

            var item = FindVisualChild.FindChild<TextBlock>(NFView, "tblAlertId"); //Problem is this line.
            alertId = Convert.ToInt32(item.Text);
            executeAlertClickCommand(ConsoleSettingsModel.GetInstance().SettingsCommandsData.AlertCommand, alertId);
        }

        internal void executeAlertClickCommand(WSMgrCommands cmd, int id) //Raising custom command
        {
            var wsParams = new WSAcknoledgedAlert();
            wsParams.alertId = id;
            if (cmd.CanExecute(wsParams))
            {
                cmd.Execute(wsParams);
            }
        }


    }

3 个答案:

答案 0 :(得分:0)

你在哪里使用这个数据模板?它在列表框中吗? 您应该能够使用 FrameworkTemplate.FindName 方法访问您的控件。首先,从ListBoxItem之一获取ContentPresenter:

ContentPresenter contentPresenter = FindVisualChild<ContentPresenter>(yourListBoxItemName);

然后从ContentPresenter获取DataTemplate:

DataTemplate yourDataTemplate = contentPresenter.ContentTemplate;

然后从DataTemplate获取MediaElement:

TextBlock yourTextBox = yourDataTemplate.FindName("tblAlertId", contentPresenter) 
as TextBlock;
if (yourTextBox != null)
{
    alertId = Convert.ToInt32(item.Text);
executeAlertClickCommand(ConsoleSettingsModel.GetInstance().SettingsCommandsData.AlertCommand, alertId);
}

有关详细信息,请参阅MSDN上的FrameworkTemplate.FindName方法页面。 http://msdn.microsoft.com/en-us/library/system.windows.frameworktemplate.findname.aspx

答案 1 :(得分:0)

尝试使用LogiclTreeHelper类找到文本块,例如

public class Contacts {


    private Bitmap bmp;
    private String baby_name;
    private String baby_gender;
    private String date;
    private String time;

    public Contacts(Bitmap b, String n, String g, String d, String t) {
        bmp = b;
        baby_name = n;
        baby_gender = g;
        date = d;
        time = t;
    }
    public Bitmap getBmp() {
        return bmp;
    }

    public String getBaby_name() {
        return baby_name;
    }

    public String getBaby_gender() {
        return baby_gender;
    }

    public String getDate() {
        return date;
    }

    public String getTime() {
        return time;
    }
}

替换行while(dpParent.GetType()。BaseType!= typeof(TextBlock));

答案 2 :(得分:0)

对我来说,由于我已在运行时添加了控件,因此必须在使用findName方法之前注册它们。

StackPanel sp = new StackPanel
{
   Name = "mySP",
   Orientation = Orientation.Horizontal,
};

//need to register the control so i can find it by name
RegisterName(sp.Name, sp);

//now I can find control by name 
StackPanel sp = (StackPanel)mainStackPanel.FindName("mySP");