6

私は WPF が初めてで、MVVM フレームワークを使用してサンプル アプリケーションを構築しようとしています。私のアプリケーションには、顧客情報を入力するためのテキストボックス、状態を表示するためのコンボボックス、および保存ボタンを含む xaml ファイルがあります。すべてのデータバインディングは、ViewModel(CustomerViewMode) を介して行われます。ViewModel(CustomerViewMode) は、Model(Customer) への参照を持ち、必要なフィールドとその Getter、setter を含みます。viewModel には CustomerList プロパティがあります。保存ボタンをクリックすると、ListBox に Customer の FirstName プロパティと LastName プロパティを表示したいと考えています。ここが問題です。コードをデバッグしました (コード ビハインドのボタンのクリック イベント)。CustomerList に最初の Customer オブジェクトとそのすべての詳細が含まれていることがわかりますが、リストボックスには表示されません。私のコードは次のとおりです。

enter code here
namespace SampleMVVM.Models
{
class Customer : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private String _firstName;
    private String _lastName;
    private Address _customerAddress;


    public String FirstName
    {
        get { return _firstName; }
        set
        {
            if (value != _firstName)
            {
                _firstName = value;
                RaisePropertyChanged("FirstName");
            }
        }
    }

    public String LastName
    {
        get { return _lastName; }
        set
        {
            if (value != _lastName)
            {
                _lastName = value;
                RaisePropertyChanged("LastName");
            }
        }
    }

    public Address CustomerAddress
    {
        get { return _customerAddress; }
        set
        {
            if (value != _customerAddress)
            {
                _customerAddress = value;
                RaisePropertyChanged("CustomerAddress");
            }
        }
    }

    private void RaisePropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }


}

}

住所(モデル)

namespace SampleMVVM.Models
{
class Address : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private string _addressLine1;
    private string _addressLine2;
    private string _city;
    //private string _selectedState;
    private string _postalCode;
    private string _country;






    public String AddressLine1
    {
        get { return _addressLine1; }
        set
        {
            if (value != _addressLine1)
            {
                _addressLine1 = value;
                RaisePropertyChanged(AddressLine1);
            }
        }
    }

    public String AddressLine2
    {
        get { return _addressLine2; }
        set
        {
            if (value != _addressLine2)
            {
                _addressLine2 = value;
                RaisePropertyChanged(AddressLine2);
            }
        }
    }

    public String City
    {
        get { return _city; }
        set
        {
            if (value != _city)
            {
                _city = value;
                RaisePropertyChanged(City);
            }
        }
    }




    public String PostalCode
    {
        get { return _postalCode; }
        set
        {
            if (value != _postalCode)
            {
                _postalCode = value;
                RaisePropertyChanged(PostalCode);
            }
        }
    }

    public String Country
    {
        get { return _country; }
        set
        {
            if (value != _country)
            {
                _country = value;
                RaisePropertyChanged(Country);
            }
        }
    }

    private void RaisePropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

}

CustomerViewModel:

namespace SampleMVVM.ViewModels
{
class CustomerViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private Customer _customer;
    RelayCommand _saveCommand;
    private List<String> _stateList = new List<string>();
    private string _selectedState;

    private ObservableCollection<Customer> _customerList = new ObservableCollection<Customer>();


    //public CustomerViewModel(ObservableCollection<Customer> customers)
    //{
    //    _customers = new ListCollectionView(customers);

    //}



    public Customer CustomerModel
    {
        get { return _customer; }
        set
        {
            if (value != _customer)
            {
                _customer = value;
                RaisePropertyChanged("CustomerModel");
            }
        }
    }

    public List<String> StateList
    {
        get
        {

            return _stateList;
        }
        set { _stateList = value; }

    }

    public ObservableCollection<Customer> CustomerList
    {
        get
        {

            return _customerList;
        }
        set
        {
            if (value != _customerList)
            {
                _customerList = value;
                RaisePropertyChanged("CustomerList");
            }

        }

    }


    public CustomerViewModel()
    {
        CustomerModel = new Customer
        {
            FirstName = "Fred",
            LastName = "Anders",

            CustomerAddress = new Address
            {
                AddressLine1 = "Northeastern University",
                AddressLine2 = "360, Huntington Avenue",
                City = "Boston",
                PostalCode = "02115",
                Country = "US",


            }
        };

        StateList = new List<String>
        {
            "Alaska", "Arizona", "California", "Connecticut", "Massachusetts", "New Jersey", "Pennsylvania", "Texas"
        };
        SelectedState = StateList.FirstOrDefault();


    }

    public String SelectedState
    {
        get { return _selectedState; }
        set
        {
            if (value != _selectedState)
            {
                _selectedState = value;
                RaisePropertyChanged(SelectedState);
            }
        }
    }

    private void RaisePropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

        }

}

CustomerInfo.xaml(表示)

<UserControl x:Class="SampleMVVM.Views.CustomerInfo"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:ViewModels="clr-namespace:SampleMVVM.ViewModels"             
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">

<UserControl.DataContext>
    <ViewModels:CustomerViewModel />
</UserControl.DataContext>



<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>


    <!--Starting label-->
    <TextBlock FontSize="18" FontFamily="Comic Sans MS" FontWeight="ExtraBlack" 
               Foreground="Navy" 
               Grid.Row="0" HorizontalAlignment="Center">
        <TextBlock.Text>
            Customer Information:
        </TextBlock.Text>
    </TextBlock>

    <TextBlock Text="First name: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top"
               Grid.Row="1" Width="80px" Height="50px" Margin="40,5,0,0"/>
    <TextBox Text="{Binding CustomerModel.FirstName}" Grid.RowSpan="2" HorizontalAlignment="Left" 
             VerticalAlignment="Top"
             Grid.Row="1" Grid.Column="1" Width="80px" Height="20px" Margin="20,5,0,0"  Name="fname"/>

    <TextBlock Text="Last Name: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top"
               Grid.Row="2" Width="80px" Height="50px" Margin="40,5,0,0"/>
    <TextBox Text="{Binding CustomerModel.LastName}" Grid.RowSpan="2" HorizontalAlignment="Left" 
             VerticalAlignment="Top"
             Grid.Row="2" Grid.Column="1" Width="80px" Height="20px" Margin="20,5,0,0" Name="lname"/>

    <TextBlock Text="Address: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top"
               Grid.Row="3" Width="80px" Height="50px" Margin="40,5,0,0"/>
    <TextBox Text="{Binding CustomerModel.CustomerAddress.AddressLine1}" Grid.RowSpan="2" HorizontalAlignment="Left" 
             VerticalAlignment="Top"
             Grid.Row="3" Grid.Column="1" Width="160px" Height="20px" Margin="20,5,0,0"/>
    <TextBox Text="{Binding CustomerModel.CustomerAddress.AddressLine2}" Grid.RowSpan="2" HorizontalAlignment="Left" 
             VerticalAlignment="Top"
             Grid.Row="4" Grid.Column="1" Width="160px" Height="30px" Margin="20,5,0,0"/>

    <TextBlock Text="City: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top"
               Grid.Row="5" Width="80px" Height="20px" Margin="40,5,0,0"/>
    <TextBox Text="{Binding CustomerModel.CustomerAddress.City}" Grid.RowSpan="2" HorizontalAlignment="Left" 
             VerticalAlignment="Top"
             Grid.Row="5" Grid.Column="1" Width="80px" Height="20px" Margin="20,5,0,0"/>

    <TextBlock Text="State: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top"
               Grid.Row="6" Width="80px" Height="20px" Margin="40,5,0,0"/>
    <ComboBox Grid.RowSpan="2" HorizontalAlignment="Left" Name="listOfSates"
              VerticalAlignment="Top" 
              Grid.Row="6" Grid.Column="1" Width="80px" Height="20px" Margin="20,5,0,0"
              ItemsSource="{Binding Path=StateList}" 
              SelectedItem="{Binding Path=SelectedState}"
              SelectionChanged="ComboBox_SelectionChanged"
              >


    </ComboBox>

    <TextBlock Text="PostalCode: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top"
               Grid.Row="7" Width="80px" Height="20px" Margin="40,5,0,0"/>
    <TextBox Text="{Binding CustomerModel.CustomerAddress.PostalCode}"  Grid.RowSpan="2" HorizontalAlignment="Left" 
             VerticalAlignment="Top"
             Grid.Row="7" Grid.Column="1" Width="80px" Height="20px" Margin="20,5,0,0"/>

    <TextBlock Text="Country: " Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top"
               Grid.Row="8" Width="80px" Height="20px" Margin="40,5,0,0"/>
    <TextBox Text="{Binding CustomerModel.CustomerAddress.Country}" Grid.RowSpan="2" HorizontalAlignment="Left" 
             VerticalAlignment="Top"
             Grid.Row="8" Grid.Column="1" Width="80px" Height="20px" Margin="20,5,0,0"/>

    <Button Content="Save" Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top"
            Grid.Row="9"  Width="50px" Height="20px" Name="savebtn" Margin="40,5,0,0"
             Click="savebtn_Click"/>


    <ListBox Name="cList" ItemsSource="{Binding Path=CustomerList}"
             HorizontalAlignment="Left" 
             VerticalAlignment="Top"
             Grid.Row="1" Grid.Column="2" Grid.RowSpan="2" Width="200px" Height="300px" Margin="200,5,0,0">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding CustomerModel.FirstName}"
                           FontWeight="Bold" Foreground="Navy"/>
                    <TextBlock Text=", " />
                    <TextBlock Text="{Binding CustomerModel.LastName}"
                           FontWeight="Bold" Foreground="Navy"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

CustomerInfo(コード ビハインド クラス)

namespace SampleMVVM.Views
{
/// <summary>
/// Interaction logic for CustomerInfo.xaml
/// </summary>
public partial class CustomerInfo : UserControl
{
    public CustomerInfo()
    {
        InitializeComponent();

        //checkvalue();
    }

            private void savebtn_Click(object sender, RoutedEventArgs e)
    {
        ////Customer c = new Customer();
        ////c.FirstName = fname.Text;
        ////c.LastName = lname.Text;
        //CustomerViewModel cvm = new CustomerViewModel();
        //cvm.CustomerModel.FirstName = fname.Text;
        //cvm.CustomerModel.LastName = lname.Text;
        //List<CustomerViewModel> customerList = new List<CustomerViewModel>();
        //customerList.Add(cvm);
        var viewModel = DataContext as CustomerViewModel;


        if (viewModel != null)
        {

            //viewModel.ShowCustomerInfo();
            String strfname = viewModel.CustomerModel.FirstName;
            String strname = viewModel.CustomerModel.LastName;

            viewModel.CustomerList.Add(viewModel.CustomerModel);
            String str1 = viewModel.CustomerList.FirstOrDefault().FirstName;
            int i = viewModel.CustomerList.Count();
            //cList.ItemsSource = viewModel.CustomerList;

        }

    }

    private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        CustomerViewModel cvm = new CustomerViewModel();
        cvm.SelectedState = listOfSates.SelectedItem.ToString();
    }




}

}

どこが間違っているのか理解できません...誰か助けてください

4

4 に答える 4

3

コード内 (Customer View Model コンストラクター内) で、CustomerModel オブジェクトの新しいインスタンスを 1 回だけ作成します。そのため、新しい顧客オブジェクトを作成するのではなく、常に同じ顧客オブジェクトを更新しています。

クリック ハンドラーの最後で、次のことを行う必要があります。

viewModel.CustomerModel = new Customer();

でも

クリック ハンドラーではなく、新しい顧客を追加するためのビュー モデルに ICommand が必要です。次に、ボタンのコマンドをビューモデルの ICommand にバインドする必要があります。

于 2012-06-07T20:10:23.483 に答える
3

そして、正しいバインディングのためにListBox.ItemTemplate

<TextBlock Text="{Binding FirstName}"
           FontWeight="Bold" Foreground="Navy"/>
<TextBlock Text="{Binding LastName}"
           FontWeight="Bold" Foreground="Navy"/>

DataContextListBoxItemすでに顧客です。

于 2012-06-08T00:26:08.277 に答える
2

ininterconent がリストボックスの itemssource の横にあるプロパティ名 customerlist をチェックするため、waid ではない CustomerLIst.FirstName をバインドしていました。そして、それは彼らのものではないので、サイレントエラーが発生しますが、GUIには表示されません.必要なのは、最初の名前と最後の名前のような機能するプロパティ名を提供することだけです.

リストボックスでのバインド以外はすべて問題ありません。以下のようにリストボックスバインディングを置き換えるだけです。

  <TextBlock Grid.Row="0"
                   Grid.Column="2"
                   HorizontalAlignment="Center"
                   VerticalAlignment="Center"
                   Text="List of Customers" />
        <ListBox Name="cList"
                 Grid.Row="1"
                 Grid.RowSpan="8"
                 Grid.Column="2"
                 ItemsSource="{Binding CustomerList}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock FontWeight="Bold"
                                   Foreground="Black"
                                   Text="{Binding FirstName}" />
                        <TextBlock Text=", " />
                        <TextBlock FontWeight="Bold"
                                   Foreground="Black"
                                   Text="{Binding LastName}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <TextBlock Grid.Row="10"
                   Grid.Column="2"
                   HorizontalAlignment="Center"
                   VerticalAlignment="Center"
                   Text="{Binding CustomerList.Count,
                                  StringFormat='Total Customers, ={0}'}" />

イベントの代わりにコマンドを取る方が良いです。

于 2012-06-08T05:12:04.530 に答える
1

問題は次のコード行にあります。

RaisePropertyChanged("CustomerList");

コレクションの追加/削除イベントでは機能しません。ObservableCollection と Item PropertyChangedを見てください。

MVVM では、コード ビハインドに多くのコード (あるとしても) を含めないでください。コマンドの使用を検討してください。

于 2012-06-07T20:03:16.803 に答える