2013-07-07 5 views
1

Я собирался создать это с формами окон, но мне сказали, что wpf mvvm будет лучше. Я новичок в C# и изучал mvvm и wpf.MVVM ViewModel создание и привязка

Теперь я работаю над своей моделью просмотра, чтобы работать как с представлением, так и с моделью. Нет базы данных.


Моя проблема:

как я правильно связать вид на ViewModel. Мне не хватает кода источника данных или localsource где-то в моем xaml, но я также не понимаю, как работает sourceource. Где в viewmodel объявляется источник и как. Я хорошо разбираюсь в поисковых системах, но до сих пор не нашел того, что заставляет его нажимать на меня.

Я также знаю, что есть свойство типа INotifyChange, и я видел примеры кода, но не понимаю его полностью, он просто не нажал на меня.


В настоящее время:

У меня есть представление, созданное в XAML, который является первым ниже код. Затем я создал класс для проверки, который является второй группой кода ниже в C# (я знаю, что методы get set могут быть улучшены, но я следил за учебником).

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


Дополнительно:

Нижняя часть (DataView) представляет собой временную таблицу для показа предыдущих сканирований, но я могу понять, что наше позже. Самая важная часть - это возможность получить сканирование и сделать с ними что-то.

Сканирование будет keywedge (посылает символы, как набирается с ключом ввода в конце), но позже я планирую сделать их последовательным COM-портом, чтобы эта программа могла работать в фоновом режиме.

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

<Window x:Class="ScanningV2.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="700"> 
    <DockPanel LastChildFill="True"> 
     <Grid x:Name="LayoutRoot" DockPanel.Dock="Top" Height="100" Background="#FFFFFF" Margin="2,2,2,2"> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="*"></RowDefinition> 
      </Grid.RowDefinitions> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="150"></ColumnDefinition> 
       <ColumnDefinition Width="*"></ColumnDefinition> 
      </Grid.ColumnDefinitions> 
      <Button Grid.Row="0" Grid.Column="0" Content="Scan" Grid.ColumnSpan="1" Margin="2,2,2.2,2" /> 
      <Label Content="Operator Barcode" Grid.Column="1" HorizontalAlignment="Left" Margin="50,20,0,0" VerticalAlignment="Top" Width="120" /> 
      <Label Content="MO/Task Barcode" Grid.Column="1" HorizontalAlignment="Left" Margin="200,20,0,0" VerticalAlignment="Top" Width="120" /> 
      <Label Content="Quantity" Grid.Column="1" HorizontalAlignment="Left" Margin="350,20,0,0" VerticalAlignment="Top" Width="120" /> 
      <TextBox Grid.Column="1" HorizontalAlignment="Left" Margin="50,50,0,0" TextWrapping="Wrap" Text="Scan" VerticalAlignment="Top" Height="20" Width="120" /> 
      <TextBox Grid.Column="1" HorizontalAlignment="Left" Margin="200,50,0,0" TextWrapping="Wrap" Text="Scan" VerticalAlignment="Top" Height="20" Width="120" /> 
      <TextBox Grid.Column="1" HorizontalAlignment="Left" Margin="350,50,0,0" TextWrapping="Wrap" Text="Scan" VerticalAlignment="Top" Height="20" Width="120" /> 

      <!--   <ListView Grid.Row="0" Grid.Column="1" x:Name="curScans" Background="Aqua" Grid.ColumnSpan="1" Margin="1.8,0,-0.4,0"> 
       <ListView.View> 
        <GridView> 
         <GridViewColumn Header="Scanner" DisplayMemberBinding="{Binding Path=curScanNum}" Width="150" /> 
         <GridViewColumn Header="Operator" DisplayMemberBinding="{Binding Path=curOperator}" Width="200" /> 
         <GridViewColumn Header="Task" DisplayMemberBinding="{Binding Path=curTask}" Width="200"/> 
        </GridView> 
       </ListView.View> 
      </ListView> --> 
     </Grid> 
     <ListView x:Name="pastScans" Background="#2FFFFFFF" DockPanel.Dock="Bottom"> 
      <ListView.View> 
       <GridView> 
        <GridViewColumn Header="Scanner" DisplayMemberBinding="{Binding Path=ScannerNum}" Width="100" /> 
        <GridViewColumn Header="Operator barcode" DisplayMemberBinding="{Binding Path=Operator}" Width="150" /> 
        <GridViewColumn Header="MO/Task barcode" DisplayMemberBinding="{Binding Path=Task}" Width="150" /> 
        <GridViewColumn Header="Date" DisplayMemberBinding="{Binding Path=ScanDate}" Width="100" /> 
        <GridViewColumn Header="Time" DisplayMemberBinding="{Binding Path=ScanTime}" Width="100" /> 
        <GridViewColumn Header="Quantity" DisplayMemberBinding="{Binding Path=Quantity}" Width="100" /> 
       </GridView> 
      </ListView.View> 
     </ListView> 

    </DockPanel> 

</Window> 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace ScanningV2 
{ 
    class scan 
    { 
     //Member variables 
     private string operatorCode; 
     public string OperatorCode 
     { 
      get { return operatorCode; } 
      set { operatorCode = value; } 
     } 

     private string taskCode; 
     public string TaskCode 
     { 
      get { return taskCode; } 
      set { taskCode = value; } 
     } 

     private int count; 
     public int Count 
     { 
      get { return count; } 
      set { count = value; } 
     } 

     private DateTime scanDateTime; 
     public DateTime ScanDateTime 
     { 
      get { return scanDateTime; } 
      set { scanDateTime = value; } 
     } 

     //Default Constructor 
     public scan() 
     { 
      operatorCode = null; 
      taskCode = null; 
      count = 0; 
     } 

     //Overload Constructor 
     public scan(string OperCode, string TaskMOCode, int CountNum) 
     { 
      operatorCode = OperCode; 
      taskCode = TaskMOCode; 
      count = CountNum; 
     } 
    } 
} 
+0

Ваш класс сканирования должен наследовать от INotifyPropertyChanged, и каждый экземпляр должен находиться в наблюдаемой коллекции. Это наблюдаемая коллекция, которая должна быть создана в вашей виртуальной машине и привязана к свойству источника элемента управления ListView. Получение фрагмента генерации свойства C# сохранит ваш LIFE с точки зрения рефакторинга вашего класса «сканирование»! –

ответ

0

Вам нужно будет установить экземпляр класса вашей модели представления в качестве DataContext вашего представления. Я обычно делаю это в коде-позади с точки зрения, так и в ваших MainWindow.xaml.cs вы могли бы сделать следующее:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 

     DataContext = new Scan(); 
    } 
} 

Имейте в виду, что ваш взгляд не сможет обнаружить изменения, если вы уведомить об этом.Это точка INotifyPropertyChanged интерфейса:

class Scan : INotifyPropertyChanged 
{ 
    // Implementing the INotifyPropertyChanged interface: 
    public event PropertyChangedEventHandler PropertyChanged; 

    // A utility method to make raising the above event a little easier: 
    protected void RaisePropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    // Then, notify the view about changes whenever a property is set: 
    private string operatorCode; 
    public string OperatorCode 
    { 
     get { return operatorCode; } 
     set { operatorCode = value; RaisePropertyChanged("OperatorCode"); } 
    } 
} 

В вашем MainWindow.xaml, вы можете привязать к этому свойству:

<TextBlock Text="{Binding OperatorCode}" /> 

Теперь, когда вы установили новое значение для OperatorCode, ваше мнение будет уведомляется, чтобы он мог получать и отображать новое значение.

Для ItemsSources любой IEnumerable будет делать - список, массив ... однако, если вы хотите, чтобы представление было уведомлено всякий раз, когда меняется ваша коллекция, вам нужно будет использовать класс, который реализует INotifyCollectionChanged, например ObservableCollection ,

Таким образом, вы создаете связываемое свойство в ваших показах модели:

private ObservableCollection<string> names; 
public ObservableCollection<string> Names 
{ 
    get { return names; } 
    set { names = value; RaisePropertyChanged("Names"); } 
} 

И вы связываете к тому, что из вашего зрения:

<ListView ItemsSource="{Binding Names}" /> 

мелочи: в C#, имена классов обычно пишутся в CamelCase. Кроме того, лично я предпочитаю, чтобы каждый класс view-model стал postfix для ViewModel, поэтому вы можете быстро увидеть, какие классы предназначены для просмотра моделей. Я пытаюсь совместить их имя с именем представления, к которому они принадлежат, поэтому вместо «scan» я бы назвал это «MainWindowViewModel».

+0

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

0

Вы не можете связать любое из этого каких-либо элементов пользовательского интерфейса WPF, потому что ваш код слишком Java-подобный.

Вы должны использовать Properties путь C#.

изменить все ваши get() и set() методы для реальных объектов.

+0

Спасибо, HighCore для начала. Я правильно их поменял, полагаю. – BrinkDaDrink

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