Объект, созданный в XAML, не может быть вызван x: Name в cs - PullRequest
0 голосов
/ 02 октября 2019

Следующий код представляет собой простой проект, в котором я пытаюсь вызвать объекты, созданные в XAML. Итак, я называю их x:Name. В тестовом интерфейсе я создал сетку из трех строк. Вторая и третья строки заполняются непосредственно Label2 и Label3, но первая строка заполняется косвенно, через Window.Resources.

Проблема в том, что myLabel2 и myLabel3 распознаются в MainWindow.xaml.cs (автозаполнение работает для них), но для myLabel1 я получаю сообщение об ошибке en:

The name 'myLabel1' does not exist in the current project

Итак, я предполагаю, что проблема проистекает из фактачто myLabel1 было создано внутри Window.Resources.

Будем благодарны за любые мысли.

Это код MainWindow.xaml:

 <Window x:Class="test2.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:test2"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <Window.Resources>
        <DataTemplate x:Key="something">
            <Label x:Name="myLabel1" Content="Labe1"/>
        </DataTemplate>
    </Window.Resources>

        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <ContentPresenter Grid.Row="0" ContentTemplate="{StaticResource something}" />
            <Label x:Name="myLabel2" Content="Labe2" Grid.Row="1" />
            <Label x:Name="myLabel3" Content="Labe3" Grid.Row="2" />
        </Grid>

</Window>

Это код MainWindow.xaml.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace test2
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            myLabel2.Content = "new content myLabel2";
            myLabel3.Content = "new content myLabel3";
            myLabel1.Content = "new content myLabel1";
        }
    }
}

РЕДАКТИРОВАТЬ: Могу ли я использовать в .cs что-то вроде this.Resources["something"]?

Это было слабо адаптивно с Как определить и использовать ресурсы в xaml, чтобы их можно было использовать в C #

1 Ответ

1 голос
/ 04 октября 2019

Как отметил один из комментаторов, содержимое вашего DataTemplate не существует до тех пор, пока ContentPresenter не создаст его экземпляр для объекта данных.

Поскольку myLabel1 находится внутри DataTemplate, вы, вероятно, захотите, чтобы содержимое вашего Label былона основе любого объекта данных, который вы отображаете в вашем ContentPresenter.

Вы ничего не сказали о своем объекте данных, поэтому предположим, что данные являются экземпляром класса с именем Widget:

public class Widget
{
    public string Title { get; set; }
}

Теперь код, который создает экземпляр вашего объекта данных (экземпляр Widget), может установить значение свойства Title. Например:

public MainWindow()
{
    InitializeComponent();
    myLabel2.Content = "new content myLabel2";
    myLabel3.Content = "new content myLabel3";

    Widget widgetItem = new Widget();
    widgetItem.Title = "new content myLabel1";

    // You could set this elsewhere, but I'm doing it here to simplify this example.
    myContentPresenter.Content = widgetItem;
}

Обратите внимание, что я дал вашему ContentPresenter имя, чтобы я мог назначить его содержимое для примера:

<ContentPresenter x:Name="myContentPresenter" Grid.Row="0" ContentTemplate="{StaticResource something}" />

Затем в вашем XAML свяжите ваши меткиСвойство Content для свойства Title объекта данных:

<Window.Resources>
    <DataTemplate x:Key="something">
        <Label x:Name="myLabel1" Content="{Binding Title}"/>
    </DataTemplate>
</Window.Resources>

Если вы хотите иметь возможность изменить значение widgetItem.Title после начальной привязки и увидеть, что это изменение отражается в пользовательском интерфейсе, тогда класс вашего объекта данных(Виджет в этом случае) должен будет реализовать INotifyPropertyChanged или наследовать DependencyObject. Я оставлю это на ваше усмотрение, чтобы расследовать это самостоятельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...