티스토리 뷰

WPF .NET

Kiosk 만들기 - Part6

kaki104 2023. 10. 27. 10:00
반응형

메뉴 화면에서 이전, 다음 버튼을 눌러서 상품 목록 페이징하는 작업, 동일 상품 선택시 주문 수량 추가, 금액 업데이트 방법 변경을 작업합니다.

1. 이전, 다음 상품 목록 출력

이전 버튼 커맨드와 다음 버튼 커맨드를 변경하고, 버튼 클릭시 이전, 다음 상품목록을 출력합니다.

SelectMenu.xaml

<Button
    Grid.Row="1"
    Grid.Column="0"
    Margin="10"
    Padding="10"
    HorizontalAlignment="Left"
    Command="{Binding PreviousCommand}"
    CommandParameter="kiosk"
    Content="이전" />
<Button
    Grid.Row="1"
    Grid.Column="0"
    Margin="10"
    Padding="10"
    HorizontalAlignment="Right"
    Command="{Binding NextCommand}"
    CommandParameter="kiosk"
    Content="다음" />

SelectMenuViewModel.cs

/// <summary>
/// 한 페이지에 노출할 상품 수
/// </summary>
private const int _pageSize = 4;

private int _currentPage;
/// <summary>
/// 현재 페이지 인덱스
/// </summary>
public int CurrentPage
{
    get { return _currentPage; }
    set { SetProperty(ref _currentPage, value); }
}

/// <summary>
/// 전체 페이지 수
/// </summary>
private int _totalPages;
/// <summary>
/// 전체 상품 목록
/// </summary>
private List<Product> _allCoffes;

//......중간 생략

/// <summary>
/// 이전 상품
/// </summary>
public ICommand PreviousCommand { get; set; }
/// <summary>
/// 다음 상품
/// </summary>
public ICommand NextCommand { get; set; }

//......중간 생략

private void Init()
{
    _allCoffes = new List<Product>
    {
        new Product{ Category = Commons.ProductCategory.Coffee, Name = "아이스 아메리카노", Price = 1500, ImageUri = new Uri("pack://application:,,,/Assets/Images/delicious-ice-cream-in-studio.jpg") },
        //상품목록 생략
    };
    SelectProductCommand = new DelegateCommand<Product>(OnSelectProduct);
    PaymentCommand = new DelegateCommand(OnPayment);
    PreviousCommand = new DelegateCommand(OnPrevious, () => CurrentPage > 0)
                        .ObservesProperty(() => CurrentPage);
    NextCommand = new DelegateCommand(OnNext, () => CurrentPage < _totalPages)
                        .ObservesProperty(() => CurrentPage);
    //......중간 생략
    //전체 페이지
    _totalPages = _allCoffes.Count / _pageSize - 1;
    DisplayProducts(CurrentPage);
}

/// <summary>
/// 상품 목록 출력
/// </summary>
/// <param name="pageIndex"></param>
private void DisplayProducts(int pageIndex)
{
    CurrentPage = pageIndex;
    Coffees = _allCoffes.Skip(CurrentPage * _pageSize).Take(_pageSize).ToList();
}
/// <summary>
/// 다음 페이지 상품 목록 조회
/// </summary>
private void OnNext()
{
    if(CurrentPage < _totalPages)
    {
        DisplayProducts(CurrentPage + 1);
    }
}
/// <summary>
/// 이전 페이지 상품 목록 조회
/// </summary>
private void OnPrevious()
{
    if(CurrentPage > 0)
    {
        DisplayProducts(CurrentPage - 1);
    }
}

* 화면이 시작하면서, 각 TabItem별로 전체 상품목록을 입력합니다.

이 예제에서는 _allCoffees라는 필드에 첫번째 TabItem에 출력할 상품 목록들만 입력하고 사용합니다.

* _totalPages를 계산해서 입력해 놓습니다. 

TabItem마다 totalPage값을 가지고 있어야 합니다. 여기서는 첫번째 TabItem만을 기준으로 합니다.

* DisplayProducts(CurrentPage)를 호출해서 첫번째 TabItem의 기본 상품목록만 출력하도록 합니다.

* 출력 방식은 전체 아이템에서 페이지 번호 만큼 Skip하고 Take를 이용해서 화면에 출력할 목록만 Coffees에 입력하는 방식을 사용합니다.

Coffees = _allCoffes.Skip(CurrentPage * _pageSize).Take(_pageSize).ToList();

* 다음과 이전 버튼을 누를 때 CurrentPage를 더하거나 뺀 후에 DisplayProducts()를 호출합니다.

2. 상품 수량 변경

* 상품을 선택하면 OnSelectProduct() 메서드를 호출하게됩니다. 이 때 선택한 상품명(여기서는 코드가 없어서)을 이용해서 동일 상품이 있는지 확인해서 존재하면 해당 상품의 수량을 +해 줍니다.

//이미 등록된 상품이라면 수량을 +1함
var existItem = AppContext.CurrentOrder.Items.FirstOrDefault(od => od.ProductName == product.Name);
if (existItem != null)
{
    //추가
    existItem.Quantity++;
}

화면에 +, - 버튼을 눌러서 직접 수량 변경

<DataGridTemplateColumn>
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <Button
                    Width="20"
                    Command="{Binding RelativeSource={RelativeSource AncestorType=DataGrid}, Path=DataContext.AddCommand}"
                    CommandParameter="{Binding}"
                    Content="+" />
                <Button
                    Width="20"
                    Command="{Binding RelativeSource={RelativeSource AncestorType=DataGrid}, Path=DataContext.RemoveCommand}"
                    CommandParameter="{Binding}"
                    Content="-" />
            </StackPanel>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

* DataGridTemplateColumn을 이용해서 +, - 버튼을 추가합니다.

* 이전 포스트에서 Command를 찾는 방법과 CommandParameter를 이용하는 방법에 대해서 다루었습니다. 그 내용을 참고하시면 + 버튼을 눌렀을 때 어떻게 AddCommand를 호출하고, 어떤 Row에 있는 녀석을 선택한 것인지를 알 수 있습니다.

AddCommand = new DelegateCommand<OrderDetail>(OnAdd);
RemoveCommand = new DelegateCommand<OrderDetail>(OnRemove);

/// <summary>
/// 상품 삭제
/// </summary>
/// <param name="orderDetail"></param>
private void OnRemove(OrderDetail orderDetail)
{
    if (orderDetail == null)
    {
        return;
    }
    orderDetail.Quantity--;
}
/// <summary>
/// 상품 추가
/// </summary>
/// <param name="orderDetail"></param>
private void OnAdd(OrderDetail orderDetail)
{
    if(orderDetail == null)
    {
        return;
    }
    orderDetail.Quantity++;
}

* AddCommand와 RemoveCommand는 CommandParameter를 OrderDetail을 받도록 되어있습니다.

* orderDetail을 확인하고 null이 아니면 수량을 더하거나 빼도록 되어있습니다.

3. 금액 업데이트 방법 변경

OrderDetail.cs

/// <summary>
/// 단가
/// </summary>
public int UnitPrice
{
    get { return _unitPrice; }
    set { SetProperty(ref _unitPrice, value, () => RaisePropertyChanged(nameof(Amount))); }
}
private int _quantity;
/// <summary>
/// 수량
/// </summary>
public int Quantity
{
    get { return _quantity; }
    set { SetProperty(ref _quantity, value, () => RaisePropertyChanged(nameof(Amount))); }
}
/// <summary>
/// 금액
/// </summary>
public int Amount
{
    get { return Quantity * UnitPrice; }
}

* 금액 = 수량 * 단가입니다.

* 수량이나 단가가 변경되면 RaisePropertyChanged() 메서드를 이용해서, Amount 프로퍼티가 변경되었음을 알립니다. 그렇게 하면, 바인딩된 컨트롤에서 Amount 프로퍼티의 값을 다시 가져가기 때문에 변경된 금액을 가져가게 됩니다.

위에서 사용된 set { SetProperty(ref _unitPrice, value, () => .....)); 이 메서드는 Prism에서 프로퍼티가 변경된 후에 실행할 Action을 지정할 수 있도록 제공하는 메서드 입니다.
RaisePropertyChanged()는 Prism에서 제공하는 강제로 프로퍼티 체인지 이벤트를 발생시켜주는 메서드입니다.

4. 소스

GitHub - kaki104/PrismKiosk at Part6/next-previous-products

 

GitHub - kaki104/PrismKiosk

Contribute to kaki104/PrismKiosk development by creating an account on GitHub.

github.com

 

반응형

'WPF .NET' 카테고리의 다른 글

Kiosk 만들기 - Part8  (2) 2023.11.01
Kiosk 만들기 - Part7  (0) 2023.10.30
Kiosk 만들기 - Part5  (0) 2023.10.25
Kiosk 만들기 - Part4  (2) 2023.10.23
Kiosk 만들기 - Part3  (0) 2023.10.20
댓글