Lottery History Analysis Tool - learn by example wpf development

Introduction  Although I am not interested in lottery, there are still many people are fond of. They spend a lot of time and effort to analyze the history of the lottery in an attempt to find the law, for the next bet to make our hope "winning" "probability increases. Regardless of whether it makes sense history research, I used the software to realize an analysis of lottery , manual analysis lottery a few days work, now one second can be achieved.

Program Interface

 

 

Processing Theory analysis :

Program is actually lottery analysis (a lot of kind of lottery). Data format is as follows:

2010001 11 13 22 16 21 18
2010002 22 28 16 5 14 26
2010003 5 14 45 48 16 25

Each issue No. 6, optionally No. 3, No. 6, if included in the No. 3, the winning of the operator.

Lottery value in the range of 1--49, each lasting 6 are selected 3. Each bet three numbers, all bets possibility of 18,424 times, the probability of speaking, every possibility of winning the bet is 1/18424 .

Number three is the software which analyzes the probability of winning the election maximum. Statistical analysis is based on the historical record, a record number in the history of three appear more often, does not mean that the future appears more often.

 Lottery History interface 

 

 This is the ListView control, display lottery history. How to display such an interface? This type of interface is very suitable for MVVM pattern show. Are you ready data and display template, the remaining subject matter ListView to do.

ListView data to be bound is defined as follows:

 1  public class ListViewBindingItem
 2     {
 3         public string Index { get; set; } //序号
 4         public string RecordNO { get; set; } //期数
 5         public string[] Digital { get; set; }
 6         public RecordItemInFile RecordItem { get; internal set; }
 7 
 8         public int ValueIndexOf(string value)
 9         {
10             for (int i = 0; i < Digital.Length; i++)
11             {
12                 if (Digital[i] == value)
13                 {
14                     return i;
15                 }
16             }
17             return -1;
18         }
19 
20         public string StrDigital
21         {
22             get
23             {
24                 return string.Format("{0} {1} {2} {3} {4} {5}",
25                     Digital[0], Digital[1], Digital[2],
26                     Digital[3], Digital[4], Digital[5]);
27             }
28         }
29 
30     }

这个类型的定义与界面密切相关,与asp.net 中的ViewMode概念相似。如果界面只是显示字符串,把数据绑定到ListView就大功告成。但是我们想把彩票中的数字显示在圆形背景中,这时候就需要用到数据模板DataTemplate。数据模板的输入是数据和模板,输出就是你想要的界面。模板就是定义数据怎么显示的。如何处理数据如何显示有很多种方法,我只举其中一种。注:每种显示效果可能都会有多种处理方法,这是WPF的灵活性,也是wpf让人困惑的地方。

ListView XAML定义如下

   <ListView  MinHeight="260" BorderThickness="1,1,1,1"  
                      VirtualizingPanel.IsVirtualizing="True" 
                       Grid.Row="0" x:Name="lvAllDigital" >
                <ListView.View>
                    <GridView >
                        <GridViewColumn Header="序号" Width="90" DisplayMemberBinding="{Binding Path=Index}"></GridViewColumn>
                        <GridViewColumn Header="期数" Width="110" DisplayMemberBinding="{Binding Path=RecordNO}"></GridViewColumn>
                        <GridViewColumn Header="1列"  Width="55" 
                                        CellTemplate="{StaticResource ColDigital1}"></GridViewColumn>
                        <GridViewColumn Header="2列" Width="55" CellTemplate="{StaticResource ColDigital2}"></GridViewColumn>
                        <GridViewColumn Header="3列" Width="55" CellTemplate="{StaticResource ColDigital3}"></GridViewColumn>
                        <GridViewColumn Header="4列" Width="55" CellTemplate="{StaticResource ColDigital4}"></GridViewColumn>
                        <GridViewColumn Header="5列" Width="55" CellTemplate="{StaticResource ColDigital5}"></GridViewColumn>
                        <GridViewColumn Header="6列" Width="55" CellTemplate="{StaticResource ColDigital6}"></GridViewColumn>
                    </GridView>
                </ListView.View>
            </ListView>

数字显示的模板定义如下:

<DataTemplate x:Key="ColDigital1" >
            <StackPanel Margin="5,2,5,2" HorizontalAlignment="Center" Width="180">
                <local:CustomControl_digital x:Name="labelDigital1" Width="30" Height="30" 
                                             StrDigital="{Binding Path=Digital[0]}"></local:CustomControl_digital>
            </StackPanel>
        </DataTemplate>
CustomControl_digital类是一个自定义控件,这个控件就是根据输入的数字,显示圆形背景图像。这个处理也很简单。
public class CustomControl_digital : Control
    {
        public static readonly DependencyProperty StrDigitalProperty;
        public static Color defaultColor = Color.FromRgb(41, 57, 85);

        Color BackColor { get; set; } = defaultColor;

        static CustomControl_digital()
        {
            StrDigitalProperty =
          DependencyProperty.Register("StrDigital", //属性名称
          typeof(string), //属性类型
          typeof(CustomControl_digital), //该属性所有者,即将该属性注册到那个类上
          new PropertyMetadata("")); //属性默认值
            DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl_digital), new FrameworkPropertyMetadata(typeof(CustomControl_digital)));
        }

        public void SetBackColor(int index)
        {
            if (index == 0)
                BackColor = defaultColor;
            else
                BackColor = Color.FromRgb(62, 175, 14);
        }

        public int Row { get; set; } = -1;
        public int Column { get; set; }
        public string StrDigital_old { get; set; }
        public string StrDigital
        {
            get { return (string)GetValue(StrDigitalProperty); }
            set { SetValue(StrDigitalProperty, value); }
        }


        static Dictionary<Brush, Pen> _colorToPenGroup = new Dictionary<Brush, Pen>();
        public static Pen GetPen(Brush color)
        {
            if(_colorToPenGroup.TryGetValue(color,out Pen pen))
            {
                return pen;
            }

            Pen pen2 = new Pen(color, 0);
            pen2.Freeze();
            _colorToPenGroup.Add(color, pen2);
            return pen2;
        }

        static Dictionary<Color, SolidColorBrush> _colorToBrushGroup = new Dictionary<Color, SolidColorBrush>();
        public static SolidColorBrush GetBrush(Color color)
        {
            if (_colorToBrushGroup.TryGetValue(color, out SolidColorBrush brush))
            {
                return brush;
            }

            SolidColorBrush newBrush = new SolidColorBrush(color);
            newBrush.Freeze();
            _colorToBrushGroup.Add(color, newBrush);
            return newBrush;
        }

        protected override void OnRender(DrawingContext dc)
        {

            base.OnRender(dc);
            if (StrDigital == "--")
                return;

            double len = Math.Min(ActualHeight, ActualWidth);
            Point center = new Point(ActualWidth / 2, ActualHeight / 2);

            Pen pen = GetPen(Brushes.Black);
            Brush brush =  GetBrush(BackColor);

            double totalRadius = len / 2;
            double radius = totalRadius * 9 / 10;
            dc.DrawEllipse(brush, pen, center, radius, radius);

            if (!string.IsNullOrEmpty(StrDigital))
            {
                FormattedText text = new FormattedText(StrDigital, CultureInfo.CurrentCulture,
                        FlowDirection.LeftToRight, new Typeface("Verdana"), 14, Brushes.White);
                Point txtPoint = new Point(center.X - 9, center.Y - 8);
                dc.DrawText(text, txtPoint);
            }
        }
    }

因为需要绑定数据,所以需要定义依赖属性。需要重载函数 protected override void OnRender(DrawingContext dc),在这个函数中处理显示。

 彩票中奖结果界面

 

 这个也是ListView控件,只是数据模板定义不一样。数据模板定义如下:

 <DataTemplate x:Key="keyDigitalView" >
            <StackPanel Margin="5,2,5,2" HorizontalAlignment="Center" Width="180">
                <local:UserControl_DigitalView x:Name="digitalView"  
                      StrDigital="{Binding Path=StrDigital}" 
                      StrHighlight="{Binding Path=StrHighlight}">
                </local:UserControl_DigitalView>
            </StackPanel>
        </DataTemplate>

要显示这样的效果需要知道两个参数:1 需要显示哪些数字,2 哪些数字需要绿色背景。这两个参数是 StrDigital,StrHighlight。我们生成用户控件,同时定义这两个参数;为了可以绑定,参数必须定位依赖属性。

UserControl_DigitalView控件定义如下:
public partial class UserControl_DigitalView : UserControl
    {
        public static readonly DependencyProperty StrDigitalProperty;
        public static readonly DependencyProperty StrHighlightProperty;

        static UserControl_DigitalView()
        {
            StrDigitalProperty =
            DependencyProperty.Register("StrDigital", //属性名称
            typeof(string), //属性类型
            typeof(UserControl_DigitalView), //该属性所有者,即将该属性注册到那个类上
            new PropertyMetadata("")); //属性默认值

            StrHighlightProperty =
                DependencyProperty.Register("StrHighlight", //属性名称
                typeof(string), //属性类型
                typeof(UserControl_DigitalView), //该属性所有者,即将该属性注册到那个类上
                new PropertyMetadata("")); //属性默认值

            // DefaultStyleKeyProperty.OverrideMetadata(typeof(UserControl_DigitalView),
            // new FrameworkPropertyMetadata(typeof(UserControl_DigitalView)));

        }

        public string StrDigital
        {
            get { return (string)GetValue(StrDigitalProperty); }
            set { SetValue(StrDigitalProperty, value); }
        }

        public string StrHighlight
        {
            get { return (string)GetValue(StrHighlightProperty); }
            set { SetValue(StrHighlightProperty, value); }
        }

        public UserControl_DigitalView()
        {
            InitializeComponent();
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            ShowView();
        }


        Run GetRun(string digital, string[] digitalHighlight)
        {
            Run run = new Run();
            int count = digitalHighlight.Where(o => o == digital).Count();
            if (count > 0)
            {
                run.Background = Brushes.Green;
                run.Foreground = Brushes.White;
            }
            run.Text = digital;
            return run;
        }

        private void ShowView()
        {
            string[] digitals = StrDigital.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            string[] digitalHighlight = StrHighlight.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            foreach (string digital in digitals)
            {
                txtDigital.Inlines.Add(GetRun(digital, digitalHighlight));
                txtDigital.Inlines.Add(" ");
            }
        }
    }

txtDigital是TextBlock控件,该控件的Inlines属性可以保护不同字体属性的文字片段。我们需要根据StrDigital,StrHighlight参数填充这些片段。

Guess you like

Origin www.cnblogs.com/yuanchenhui/p/12114117.html