0

У меня есть дерево, как показано ниже.TreeView дочерние узлы - проверка ввода в wpf

  • R1
    • Р1
      • Ребенок 1
    • Р2
      • Ребенок 1
    • ХХ
      • Ребенок 3

Скажет я хочу, чтобы отобразить сообщение об ошибке либо в а) узле дерева или б) его контейнер

на основе значения моего правила проверки.

Для exmaple если я применить логику проверки для этого дерева,

Validation правило >>> все родители, стоимость которых начинается с «р» действует

В результате, мой узел «хх» является инвалид . Мне нужно выделить этот элемент и уведомить пользователя.

Я использую MVVM в WPF. Как мне это сделать. PLS помочь мне.

+0

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

+0

Я не знаком с триггером стиля/валидацией данных в wpf. Я не знаю, как это сделать ... –

ответ

2

я сделал что-то подобное в прошлом, вот что вы можете сделать:

  1. Создать ViewModel (например NodeViewModel), который представляет собой каждый из дерева узлов в случае, если у вас еще нет
  2. Вы можете создать и реализовать интерфейс в этом NodeViewModel, например, IValidate, который предоставляет свойство bool IsValid {get;set;}. (Убедитесь, что вы используете INotifyPropertyChanged в свойстве ViewModel)
  3. Создайте стиль для типа управления, который вы используете в своем представлении для своих узлов (например, Button), и создайте триггер стиля (много примеров в Интернете), который устанавливает узел фона на красный, когда IsValid ложно и применить его к контролю:

       <HierarchicalDataTemplate DataType="{x:Type ViewModel:NodeViewModel}" ItemsSource="{Binding Children}"> 
            <Button Style="{StaticResource MyNodeStyle}" 
              Content="{Binding Path=.}" 
           </HierarchicalDataTemplate> 
    
  4. на ваш слой бизнес-логики, или контейнер ViewModel создать метод, который проверяет все узлы деревьев рекурсивно и устанавливает IsValid свойство всем им или определить свое бизнес-правило в IsValid Get (сделать его доступным только для чтения). Когда это подтверждение произойдет, ваши узлы автоматически станут красными, если они недействительны в соответствии с вашими правилами.

Надеюсь, что это поможет, дайте мне знать, если у вас есть вопросы.

EDIT: Добавлены примеры образцов для иллюстрации решения. Мое бизнес-правило состояло в том, что любой узел, начинающийся с «p», является Valid (зеленый), независимо от того, является ли он родителем или нет, но вы получаете идею ..

public class TreeNodeViewModel : ViewModelBase<TreeNodeViewModel> 
{ 
    private string _NodeText; 
    private ObservableCollection<TreeNodeViewModel> _Children; 

    public TreeNodeViewModel() 
    { 
     Children = new ObservableCollection<TreeNodeViewModel>(); 
    } 

    public string NodeText 
    { 
     get { return _NodeText; } 
     set 
     { 
      _NodeText = value; 
      NotifyPropertyChanged(m => m.NodeText); 
      NotifyPropertyChanged(m => m.IsValid); 
     } 
    } 

    public bool IsValid 
    { 
     get { return !string.IsNullOrEmpty(NodeText) && NodeText.ToLower().StartsWith("p"); } 
    } 

    public ObservableCollection<TreeNodeViewModel> Children 
    { 
     get { return _Children; } 
     set 
     { 
      _Children = value; 
      NotifyPropertyChanged(m => m.Children); 
     } 
    } 
} 

public class TreeViewModel : ViewModelBase<TreeViewModel> 
{ 
    private ObservableCollection<TreeNodeViewModel> _RootNodeContainer; 
    private TreeNodeViewModel _RootNode; 

    public TreeViewModel() 
    { 
     InitializeTree(); 
    } 

    private void InitializeTree() 
    { 
     RootNodeContainer = new ObservableCollection<TreeNodeViewModel>(); 
     RootNode = new TreeNodeViewModel() { NodeText = "R1" }; 
     RootNodeContainer.Add(RootNode); 

     TreeNodeViewModel p1 = new TreeNodeViewModel() {NodeText = "P1"}; 
     p1.Children.Add(new TreeNodeViewModel(){NodeText = "Child1"}); 
     RootNode.Children.Add(p1); 
     TreeNodeViewModel p2 = new TreeNodeViewModel() {NodeText = "P2"}; 
     p2.Children.Add(new TreeNodeViewModel() { NodeText = "Child1" }); 
     RootNode.Children.Add(p2); 
     TreeNodeViewModel xx = new TreeNodeViewModel() {NodeText = "XX"}; 
     xx.Children.Add(new TreeNodeViewModel() { NodeText = "Child3" }); 
     RootNode.Children.Add(xx); 
    } 

    public TreeNodeViewModel RootNode 
    { 
     get { return _RootNode; } 
     set 
     { 
      _RootNode = value; 
      NotifyPropertyChanged(m => RootNode); 
     } 
    } 

    public ObservableCollection<TreeNodeViewModel> RootNodeContainer 
    { 
     get { return _RootNodeContainer; } 
     set 
     { 
      _RootNodeContainer = value; 
      NotifyPropertyChanged(m => RootNodeContainer); 
     } 
    } 
} 

<TreeView Name="GoldTree" ItemsSource="{Binding RootNodeContainer}" 
        Background="#FFF0EDD1"> 
      <TreeView.Resources> 
       <ResourceDictionary> 
        <Style TargetType="Button" x:Key="MyNodeStyle"> 
         <Style.Triggers> 
          <DataTrigger 
           Binding="{Binding Path=IsValid,UpdateSourceTrigger=PropertyChanged}" 
           Value="False"> 
           <Setter Property="Border.Background" Value="Red" /> 
          </DataTrigger> 
          <DataTrigger 
           Binding="{Binding Path=IsValid,UpdateSourceTrigger=PropertyChanged}" 
           Value="True"> 
           <Setter Property="Border.Background" Value="GreenYellow" /> 
          </DataTrigger> 
         </Style.Triggers> 
        </Style> 
        <Style TargetType="TreeViewItem"> 
         <Setter Property="Margin" Value="0,0,0,0" /> 
         <!-- Disable blue highlighting on selection--> 
         <Setter Property="Focusable" Value="false" /> 
        </Style> 
        <HierarchicalDataTemplate DataType="{x:Type ViewModel:TreeNodeViewModel}" 
               ItemsSource="{Binding Children}"> 
         <Button Style="{StaticResource MyNodeStyle}" Content="{Binding Path=NodeText}" /> 
        </HierarchicalDataTemplate> 
       </ResourceDictionary> 
      </TreeView.Resources> 
     </TreeView> 

Вот что вы получите:
Output

Ограничение этого решения является то, что проверка происходит, когда свойство NodeText устанавливается для каждого узла, так что вы можете не знать, в тот момент, является ли узел имеет детей, поэтому я предпочел бы создать метод в TreeViewModel, чтобы установить флаг IsValid для всех узлов в какой-то момент.

+0

Да. Но я не уверен, как применить правила проверки к элементу дерева. Я знаю о триггере стиля. Но как применить правила валидации к моему древовидному представлению? –

+0

Вы применяете правила проверки для своей поддержки 'ViewModel', единственная ответственность за« Просмотр »- это применить стили, которые вы определяете в своем триггере, и выделить недопустимые узлы, и это происходит автоматически после его определения. Подумайте больше о стороне ViewModel. –

+0

любой пример, поскольку я не могу представить, что сказал? –