2014-08-27 2 views
3

Я новичок в WPF am и переносит приложение из VC++ 6.0/MFC в C#/WPF (VS2013). Большая часть моей разработки окон была в VC++/MFC. Я пытаюсь придерживаться шаблона MVVM и пишу несколько доказательств концептуальных приложений, чтобы мои ноги были влажными. До сих пор у меня есть одна точка.WPF Изменение Datacontexts и представлений в том же окне

Когда мое приложение запустится, оно представит древовидный вид клиентов и счетов. У меня это хорошо работает с использованием простого иерархического шаблона данных с привязкой каждого уровня к моему локальному типу данных (модель просмотра). Я хочу, чтобы это произошло, когда выбран законопроект (прямо сейчас у меня есть кнопка, чтобы нажать на шаблон счета). Я хочу, чтобы древовидное изображение было заменено подробным представлением счета (я не хочу, чтобы диалог появлялся вверх). Startup Screen

Xaml для этого:

<DockPanel> 
    <TreeView x:Name="trvGroups" ItemsSource="{Binding LBGroups}" VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling"> 
    <TreeView.ItemContainerStyle> 
     <!-- 
      This Style binds a TreeViewItem to a LBtreeViewItemViewModel 
     --> 
     <Style TargetType="{x:Type TreeViewItem}"> 
      <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" /> 
      <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" /> 
      <Setter Property="FontWeight" Value="Normal" /> 
     </Style> 
    </TreeView.ItemContainerStyle> 

    <TreeView.Resources> 
     <HierarchicalDataTemplate 
      DataType="{x:Type local:GroupViewModel}" 
      ItemsSource="{Binding Children}" 
      > 
      <StackPanel Orientation="Horizontal"> 
       <TextBlock Text="{Binding GroupName}" /> 
      </StackPanel> 
     </HierarchicalDataTemplate> 

     <HierarchicalDataTemplate 
      DataType="{x:Type local:BillViewModel}" 
      ItemsSource="{Binding Children}"> 
      <StackPanel Orientation="Horizontal"> 
       <TextBlock Text="{Binding BillName}" /> 
       <Button Command="{Binding Path=BillEditCommand}">Edit</Button> 
      </StackPanel> 
     </HierarchicalDataTemplate> 
    </TreeView.Resources> 
    </TreeView> 
</DockPanel> 

Сейчас у меня больше вопросов, чем что-либо. Должен ли я определять каждое представление как пользовательский элемент управления и помещать его в window.resources? Я использую шаблоны данных? Я предполагаю, что я изменил бы контекст данных, чтобы указать на модель просмотра подробных счетов. Каков наилучший способ сделать это?

Моя цель, придерживаться MVVM, как я понимаю, состоит в том, чтобы не иметь ничего в коде (или как можно меньше).

Я ищу больше для указателей, чтобы начать меня по правильному пути, когда я исследую. На данный момент я немного одурманен.

Заранее спасибо.

+2

Каждый вид должен быть 'UserControl' (или' Window') и будет иметь свой собственный файл XAML и соответствующий (в основном пустой) код позади файл. Вы не определяете представления в 'Windows.Resources'. Однако вы можете вставить 'UserControl' в любом месте, где вы можете вставить стандартные элементы управления, и вы можете показать« Окно ». –

+1

Бизнес-логика входит в модель представления. Пользовательский интерфейс затрагивает код. MVVM! = No codebehind. – Will

+0

прочитал о сценариях мастера/подробностей в MVVM –

ответ

1

Я покажу вам простой мастер-файл, где вы можете выбрать модели в своем TreeView и Edit Them.

CS:

 public partial class MainWindow : Window , INotifyPropertyChanged 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     this.DataContext = this; 
    } 

    private ICommand onEditBillCommand; 
    public ICommand OnEditBillCommand 
    { 
     get 
     { 
      if (onEditBillCommand == null) 
       onEditBillCommand = new RelayCommand<Bill> 
        (
         bill => { CurrentBill = bill; } 
        ); 
      return onEditBillCommand; 
     } 
    } 

    private Bill currectBill; 
    public Bill CurrentBill 
    { 
     get { return currectBill; } 
     set 
     { 
      currectBill = value; 
      PropertyChanged(this, new PropertyChangedEventArgs("CurrentBill")); 
     } 
    } 

    public List<Customer> Customers 
    { 
     get 
     { 
      List<Customer> customers = new List<Customer>(); 
      for (int i = 0; i < 5; i++) 
      { 
       customers.Add(CreateMockCustomer(i)); 
      } 
      return customers; 
     } 
    } 

    private Customer CreateMockCustomer(int g) 
    { 
     Customer c = new Customer(); 

     c.Name = "John (" + g + ")" ; 

     for (int i = 0; i < 3; i++) 
     { 
      c.Bills.Add(CreateMockBill()); 
     } 

     return c; 
    } 

    private Bill CreateMockBill() 
    { 
     Bill b = new Bill(); 

     b.Price = 55.5; 
     b.BoughtOnDate = DateTime.Now.Date; 

     return b; 
    } 

    public event PropertyChangedEventHandler PropertyChanged = delegate { }; 
} 


public class Customer : INotifyPropertyChanged 
{ 
    private string name; 
    public string Name 
    { 
     get { return name; } 
     set { name = value; } 
    } 

    private ObservableCollection<Bill> bills; 
    public ObservableCollection<Bill> Bills 
    { 
     get 
     { 
      if (bills == null) 
      { 
       bills = new ObservableCollection<Bill>(); 
      } 
      return bills; 
     } 
    } 


    public event PropertyChangedEventHandler PropertyChanged = delegate { }; 
} 

public class Bill : INotifyPropertyChanged 
{ 
    private double price; 
    public double Price 
    { 
     get { return price; } 
     set 
     { 
      price = value; 
      PropertyChanged(this, new PropertyChangedEventArgs("Price")); 
     } 
    } 

    private DateTime boughtOnDate; 
    public DateTime BoughtOnDate 
    { 
     get { return boughtOnDate; } 
     set 
     { 
      boughtOnDate = value; 
      PropertyChanged(this, new PropertyChangedEventArgs("BoughtOnDate")); 
     } 
    } 


    public event PropertyChangedEventHandler PropertyChanged = delegate { }; 
} 

public interface IRelayCommand : ICommand 
{ 
    void RaiseCanExecuteChanged(); 
} 
public class RelayCommand<T> : IRelayCommand 
{ 
    private Predicate<T> _canExecute; 
    private Action<T> _execute; 

    public RelayCommand(Action<T> execute, Predicate<T> canExecute = null) 
    { 
     _execute = execute; 
     _canExecute = canExecute; 
    } 

    private void Execute(T parameter) 
    { 
     _execute(parameter); 
    } 

    private bool CanExecute(T parameter) 
    { 
     return _canExecute == null ? true : _canExecute(parameter); 
    } 

    public bool CanExecute(object parameter) 
    { 
     return parameter == null ? false : CanExecute((T)parameter); 
    } 

    public void Execute(object parameter) 
    { 
     _execute((T)parameter); 
    } 

    public event EventHandler CanExecuteChanged; 

    public void RaiseCanExecuteChanged() 
    { 
     var temp = Volatile.Read(ref CanExecuteChanged); 

     if (temp != null) 
      temp(this, new EventArgs()); 
    } 
} 

XAML:

 <Window> 
     <Window.Resources> 
      <HierarchicalDataTemplate x:Key="customerTemplate" DataType="{x:Type local:Customer}" ItemsSource="{Binding Bills}"> 
       <HierarchicalDataTemplate.ItemTemplate> 
        <DataTemplate> 
        <Grid> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition/> 
          <ColumnDefinition/> 
          <ColumnDefinition/> 
         </Grid.ColumnDefinitions> 

         <TextBlock Text="{Binding Price}" /> 
         <TextBlock Text="{Binding BoughtOnDate}" Grid.Column="1" /> 
         <Button Content="Edit" Grid.Column="2" 
          Command="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=DataContext.OnEditBillCommand}" 
          CommandParameter="{Binding}"/> 

        </Grid> 
       </DataTemplate> 
      </HierarchicalDataTemplate.ItemTemplate> 

      <TextBlock Text="{Binding Name}" FontFamily="Arial" FontSize="16" FontWeight="Bold" /> 

     </HierarchicalDataTemplate> 

    </Window.Resources> 

    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition /> 
      <ColumnDefinition Width="0.05*"/> 
      <ColumnDefinition /> 
     </Grid.ColumnDefinitions> 


     <TreeView ItemsSource="{Binding Customers}" ItemTemplate="{StaticResource customerTemplate}"> 

     </TreeView> 


     <Grid Grid.Column="2" DataContext="{Binding CurrentBill, Mode=OneWay}" Background="AliceBlue"> 
      <Grid.RowDefinitions> 
       <RowDefinition /> 
       <RowDefinition /> 
      </Grid.RowDefinitions> 

      <TextBox Text="{Binding Price, Mode=TwoWay}" Margin="50"/> 
      <TextBox Text="{Binding BoughtOnDate, Mode=TwoWay}" Grid.Row="1" Margin="50"/> 


     </Grid> 

    </Grid>  
+0

Это близко к тому, что я хочу, за исключением того, что я хочу, чтобы древовидное изображение «исчезло», когда детали отображаются (а затем снова появляются, когда детали закрыты). Позвольте мне играть с этой и другими идеями сверху. –

+0

Да, я знаю, я думал, что вы можете извлечь это отсюда. никаких проблем, я не могу отредактировать это, чтобы сделать это. –

Смежные вопросы