WPF Редактирование шаблона данных из окна OnInit - PullRequest
0 голосов
/ 06 февраля 2019

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

Мой Добавить новое окно машины:

private void OnInit(object sender, RoutedEventArgs e)
{
    this.DataContext = new MachineItem("Type your description here",
        MachineTypeEnum.Computer, "1.1.1.1", "1.1.1.1", 4, null, ((GUIApp)Application.Current).CurrentMachineGroup,
        BordersStyle.Blue);

    //Below are 2 lines that sudo represent what I am trying to do.
    var template = this.DataContext as TheTemplateIWant; //Wrong
    template.DeleteButton.Visibility = Visibility.Hidden; //I don't need a delete button on something I am trying to add
}

Я знаюДругой способ сделать это - изменить свойство объекта «MachineItem», а затем создать в шаблоне DataTrigger, чтобы редактировать пользовательский интерфейс на основе этого свойства (я мог бы использовать bool), но это кажется немного хакерским, потому что MachineItemобъект представляет данные и не должен отслеживать, в каком окне он находится. Я также открыт для других способов, кроме редактирования в OnInit (), если это хорошая практика

Ответы [ 2 ]

0 голосов
/ 06 февраля 2019

Вы можете использовать FrameworkElement.FindResource, чтобы найти «ближайший» ресурс по имени.Будет выполнен поиск во всех коллекциях <x.Resources> во всех элементах-предках в XAML, включая определенные в App.xaml.В конечном итоге он будет разрешать ресурс точно так же, как если бы вы использовали статический ресурс в коде XAML.

От MSDN:

Ищет ресурс с указанным ключом и выдает исключение, если запрошенный ресурс не найден.

...

Если ресурс не найден в вызывающем элементе, затем ищется родительский элемент в логическом дереве, затем приложение, затем темы и, наконец, системные ресурсы.Эта методология поиска идентична поиску дерева, если ресурс был запрошен динамической ссылкой на ресурс в разметке.Дополнительные сведения о поиске ресурсов см. В разделе Ресурсы XAML.

Как правило, вы немедленно приводите возвращаемое значение FindResource к типу свойства, которое вы устанавливаете с возвращенным значением ресурса.

Ключи ресурсане обязательно строки.Например, стили для элементов управления на уровне темы преднамеренно привязаны к типу элемента управления, а стили приложения или страницы для элементов управления обычно используют это же соглашение о ключах.Подробности см. В разделе «Стили и шаблоны» или «Ресурсы XAML».

В вашем примере это будет выглядеть примерно так:

var template = this.FindResource("TheTemplateIWant") as DataTemplate;

При всем сказанном, вы бывероятно, лучше использовать привязку данных и привязку видимости элемента к свойству модели представления, вместо того, чтобы пытаться манипулировать шаблоном программно.

0 голосов
/ 06 февраля 2019

Один из вариантов - использовать разные DataTemplate для этого окна, переопределить его в Window.Resources.

В качестве альтернативы, вы можете найти DataTemplate элементов в VisualTree после того, как окно будет отображено / присоединено к нему.

Для этого вы можете найти элементы Window по типу, имени.Например, если у вас есть DataTemplate с некоторыми элементами и кнопка с именем

 <DataTemplate DataType="{x:Type local:MachineItem}">
       <StackPanel>
            <TextBlock Text="{Binding Id}"></TextBlock>
            <TextBlock Text="{Binding Name}"></TextBlock>
            <Button x:Name="DeleteButton"> delete</Button>
       </StackPanel>
  </DataTemplate>

Вы можете найти DeleteButtons в окне, используя VisualTreeHelper как

VisualTreeHelperExtensions.FindChild<Button>(this, "DeleteButton");

Я изменил версию расширения VisualTreeHelperнайдено здесь , которое возвращает все элементы типа по имени

public static class VisualTreeHelperExtensions
{
    public static IEnumerable<T> FindChild<T>(DependencyObject parent, string childName)
        where T : DependencyObject
    {
        // Confirm parent and childName are valid. 
        if (parent == null)
        {
            yield break;
        }

        int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
        for (int i = 0; i < childrenCount; i++)
        {
            var child = VisualTreeHelper.GetChild(parent, i);
            // If the child is not of the request child type child
            T childType = child as T;
            if (childType == null)
            {
                // recursively drill down the tree
                foreach (var innerChild in FindChild<T>(child, childName))
                {
                    yield return innerChild;
                }
            }
            else if (!string.IsNullOrEmpty(childName))
            {
                var frameworkElement = child as FrameworkElement;
                // If the child's name is set for search
                if (frameworkElement != null && frameworkElement.Name == childName)
                {
                    // if the child's name is of the request name
                    yield return (T)child;
                }
            }
            else
            {
                // child element found.
                yield return (T)child;
            }
        }
    }
}

Итак, полный пример (с шаблоном, определенным выше):

    private void OnInit(object sender, RoutedEventArgs e)
    {
        this.DataContext = new MachineItem("Type your description here",
            MachineTypeEnum.Computer, "1.1.1.1", "1.1.1.1", 4, null, ((GUIApp)Application.Current).CurrentMachineGroup,
            BordersStyle.Blue);

        var buttons = VisualTreeHelperExtensions.FindChild<Button>(this, "DeleteButton");

        foreach (var button in buttons)
        {
            button.Visibility = Visibility.Hidden;
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...