하아찡
[C#/WPF] Upbit프로젝트 BidAskList 본문
선택된 코인 호가창을 보여줌. 최대 10개까지로 설정했음.
BidAskList.xaml
<UserControl x:Class="Upbit.Views.BidAskList"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:conv="clr-namespace:Upbit.Converter"
prism:ViewModelLocator.AutoWireViewModel="True">
<UserControl.Resources>
<conv:DivByThreeConverter x:Key="DivByThreeConverter"/>
<Style x:Key="ListviewItemStyle" TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Border x:Name="border" Background="Red">
<ContentPresenter Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid x:Name="g1">
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" x:Name="c1" />
<ColumnDefinition Width="1*" x:Name="c2"/>
<ColumnDefinition Width="1*" x:Name="c3" />
</Grid.ColumnDefinitions>
<Grid Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding CoinName}"/>
<TextBlock Margin="10,0,0,0" Text="{Binding Rate}"/>
</StackPanel>
</Grid>
<Grid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" >
<ListView x:Name="LvAsk" ItemsSource="{Binding AskUnits}"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
BorderThickness="0"
Background="{Binding MyColors.ColorAskBack}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction Command="{Binding CommandListViewDoubleClick}" CommandParameter="{Binding ElementName=LvAsk,Path=SelectedItem}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel VerticalAlignment="Bottom"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.Resources>
<!--상단 헤더 안보이게-->
<Style TargetType="GridViewColumnHeader">
<Setter Property="Visibility" Value="Collapsed"/>
</Style>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Center"/>
</Style>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn Header="Volume" DisplayMemberBinding="{Binding units}" Width="{Binding ActualWidth, ElementName=g1,Converter={StaticResource DivByThreeConverter}}"/>
<GridViewColumn Header="Price" DisplayMemberBinding="{Binding unitp}" Width="{Binding ActualWidth, ElementName=g1,Converter={StaticResource DivByThreeConverter}}" />
</GridView>
</ListView.View>
</ListView>
</Grid>
<Grid Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2">
<ListView x:Name="LvBid" ItemsSource="{Binding BidUnits}"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
BorderThickness="0"
Background="{Binding MyColors.ColorBidBack}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction Command="{Binding CommandListViewDoubleClick}" CommandParameter="{Binding ElementName=LvBid,Path=SelectedItem}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<ListView.Resources>
<!--상단 헤더 안보이게-->
<Style TargetType="GridViewColumnHeader">
<Setter Property="Visibility" Value="Collapsed"/>
</Style>
<Style TargetType="ListViewItem">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<!--Setter Property="BorderBrush" Value="{Binding MyColors.ColorBid}"/-->
</Trigger>
<Trigger Property="IsSelected" Value="True">
<!--Setter Property="BorderBrush" Value="{Binding MyColors.ColorBid}"/-->
<Setter Property="Background" Value="Transparent"/>
</Trigger>
</Style.Triggers>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
</Style>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn Header="Volume" DisplayMemberBinding="{Binding unitp}" Width="{Binding ActualWidth, ElementName=g1,Converter={StaticResource DivByThreeConverter}}" />
<GridViewColumn Header="Price" DisplayMemberBinding="{Binding units}" Width="{Binding ActualWidth, ElementName=g1,Converter={StaticResource DivByThreeConverter}}"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Grid>
</UserControl>
DivByThreeConverter.cs
using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows;
namespace Upbit.Converter
{
public class DivByThreeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is double width)
{
return width / 3.0;
}
return DependencyProperty.UnsetValue;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
BidAskListViewModel.cs
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using PublicColor;
using System;
using System.Collections.Generic;
using System.Linq;
using Upbit.Event;
using Upbit.Functions;
using Upbit.Functions.Interface;
using Upbit.UpbitFunctions;
using static Upbit.Structs;
namespace Upbit.ViewModels
{
public class BidAskListViewModel : BindableBase,IWebSocketTicker, IColors
{
PublicFunctions upbit = new PublicFunctions();
#region Models
/// <summary>
/// 매수 호가 목록
/// </summary>
private List<Structs.BidAskUnit> bidunits;
public List<Structs.BidAskUnit> BidUnits
{
get { return bidunits; }
set { SetProperty(ref bidunits, value); }
}
/// <summary>
/// 매도 호가창
/// </summary>
private List<Structs.BidAskUnit> askunits;
public List<Structs.BidAskUnit> AskUnits
{
get { return askunits; }
set { SetProperty(ref askunits, value); }
}
/// <summary>
/// 현재 코인명
/// </summary>
private string coinname;
public string CoinName
{
get { return coinname; }
set { SetProperty(ref coinname, value); }
}
/// <summary>
/// 등락율
/// </summary>
private string rate;
public string Rate
{
get { return rate; }
set { SetProperty(ref rate, value); }
}
private double acwidth;
public double AcWidth
{
get { return acwidth; }
set { SetProperty(ref acwidth, value); }
}
private bool BidAskType = true;
#endregion
#region Colors
/// <summary>
/// 색상 업데이트 이벤트
/// </summary>
public void EventUpdateColor()
{
MyColors.ColorText = PublicColor.Colors.Colorinstance.ColorText;
MyColors.ColorBack = PublicColor.Colors.Colorinstance.ColorBack;
MyColors.ColorBid = PublicColor.Colors.Colorinstance.ColorBid;
MyColors.ColorAsk = PublicColor.Colors.Colorinstance.ColorAsk;
MyColors.ColorBidBack = PublicColor.Colors.Colorinstance.ColorBidBack;
MyColors.ColorAskBack = PublicColor.Colors.Colorinstance.ColorAskBack;
}
private PublicColor.Colors mycolors;
public PublicColor.Colors MyColors
{
get
{
if (mycolors is null) mycolors = new PublicColor.Colors();
return mycolors;
}
set { SetProperty(ref mycolors, value); }
}
#endregion Colors
#region PrismEvent
private IEventAggregator _ea;
#endregion PrismEvent
#region Event
/// <summary>
/// 선택된 금액으로 매수 매도가 변경
/// </summary>
private DelegateCommand<object> listviewdoubleclick;
public DelegateCommand<object> CommandListViewDoubleClick =>
listviewdoubleclick ?? (listviewdoubleclick = new DelegateCommand<object>(ExecuteCommandListViewDoubleClick));
void ExecuteCommandListViewDoubleClick(object obj)
{
if (obj is null)
return;
Structs.BidAskUnit unit = (BidAskUnit)obj;
Structs.MessageCoinPirce mp = new MessageCoinPirce();
mp.Check = unit.Check;
mp.Price = unit.unitp;
_ea.GetEvent<MessageCoinPriceEvent>().Publish(mp);
}
#endregion
#region InterfaceFunctions
public void TradeEvent(Trade tr)
{
throw new NotImplementedException();
}
public void OrderEvent(Orderbook ob)
{
if (CoinName == ob.cd)
{
SetOrderBook(ob);
}
}
public void TickerEvent(Ticker tick)
{
if (CoinName == tick.cd)
{
string Change = tick.c;
string str = "";
if (Change == "RISE")
str = "+";
else if (Change == "FALL")
str = "-";
Rate = $"{str}{Math.Round(tick.cr * 100, 2)}%";
}
}
#endregion InterfaceFunctions
#region Functions
/// <summary>
/// 호가창 셋팅
/// </summary>
/// <param name="ob"></param>
private void SetOrderBook(Structs.Orderbook ob)
{
BidUnits.Clear();
AskUnits.Clear();
try
{
foreach (var item in ob.obu)
{
Structs.BidAskUnit ask = new Structs.BidAskUnit();
Structs.BidAskUnit bid = new Structs.BidAskUnit();
ask.unitp = item.ap;
ask.units = item._as;
bid.unitp = item.bp;
bid.units = item.bs;
AskUnits.Add(ask);
BidUnits.Add(bid);
}
AskUnits = Enumerable.Reverse(AskUnits).ToList();
BidUnits = BidUnits.ToList();
}
catch(Exception e)
{
}
}
private void GetCoinName(Structs.MarketCodes coinname)
{
CoinName = coinname.Market;
Rate = coinname.Rate.ToString();
SetOrderBook(upbit.OrderBook(CoinName));
Structs.MessageCoinPirce mcp = new Structs.MessageCoinPirce();
//mcp.
if(BidAskType == true)
{
//매수 타입
mcp.Price = AskUnits[AskUnits.Count - 1].unitp;
}
else
{
//매도타입
mcp.Price = BidUnits[0].unitp;
}
mcp.Check = BidAskType;
_ea.GetEvent<MessageCoinPriceEvent>().Publish(mcp);
}
private void GetBidAskType(bool b)
{
BidAskType = b;
}
#endregion Functions
public BidAskListViewModel(IEventAggregator ea)
{
_ea = ea;
_ea.GetEvent<MessageCoinNameEvent>().Subscribe(GetCoinName);
_ea.GetEvent<MessageBidAskCheckEvent>().Subscribe(GetBidAskType);
BidUnits = new List<Structs.BidAskUnit>();
AskUnits = new List<Structs.BidAskUnit>();
//웹소켓에서 받아온 OrderBook이벤트 발생
WebSocketTicker.OrderEvent += new WebSocketTicker.OrderEventHandler(OrderEvent);
WebSocketTicker.TickerEvent += new WebSocketTicker.TickEventHandler(TickerEvent);
//색변경 이벤트 등록
PublicColor.Colors.ColorUpdate += (EventUpdateColor);
}
}
}
해당 코드는 최대 호가15개로 받고 보여주는 호가를 변경 할 수 있게 수정할예정.
물론 UI쪽 디자인도 조금 다듬어야할듯.
반응형
'C# > 코인프로그램 - 코드' 카테고리의 다른 글
[C#/WPF] PublicColor 프로젝트 (1) | 2023.11.30 |
---|---|
[C#/WPF] Upbit프로젝트 CoinList (1) | 2023.11.29 |
[C#/WPF] Upbit프로젝트 Balance (1) | 2023.11.29 |
[C#/WPF] Upbit프로젝트 MyTradeClientWebSocket (0) | 2023.11.28 |
[C#/WPF] Upbit프로젝트 WebSocketTicker (1) | 2023.11.28 |