RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 932221
Accepted
Andrew_STOP_RU_AGRESSION_IN_UA
Andrew_STOP_RU_AGRESSION_IN_UA
Asked:2020-01-15 10:53:25 +0000 UTC2020-01-15 10:53:25 +0000 UTC 2020-01-15 10:53:25 +0000 UTC

如何在 WPF 中正确实现这样的日历?具有定制设计的复杂组件

  • 772

假设我有课:

public class YearOfLife
{
    public int YearAbsolute;
    public int YearRelative;

    public List<Week> Weeks = new List<Week>();
}

public class Week
{
    public string Tooltip;

    public WeekType WeekType;

    public DateTime Start;
    public DateTime End;
}

public enum WeekType
{
    Empty,
    Passed,
    Future,
    PossibleFuture
}

假设我有一个生成数据的代码:

List<YearOfLife> Life = new List<YearOfLife>()

public void ReGenerateLife()
{
    Life.Clear();

    var yearStart = new DateTime(DayBirth.Year, 1, 1, 0, 0, 0);
    yearStart = yearStart.AddDays(8 - (int)yearStart.DayOfWeek);

    for (var i = yearStart; i <= DayDeath2; i = i.AddYears(1))
    {
        var tmpYear = new YearOfLife();
        tmpYear.YearAbsolute = i.Year;
        tmpYear.YearRelative = i.Year - DayBirth.Year;

        Life.Add(tmpYear);
    }

    var currDate = yearStart;

    while (currDate <= DayDeath2)
    {
        var lstItem = Life.Where(a => a.YearAbsolute == currDate.Year).ToList()[0];

        var week = new Week();
        week.Start = currDate;
        week.End = currDate.AddDays(6);

        if (currDate < DayBirth)
        {
            week.WeekType = WeekType.Empty;
        }
        else if (currDate <= DateTime.Today)
        {
            week.WeekType = WeekType.Passed;
        }
        else if (currDate <= DayDeath)
        {
            week.WeekType = WeekType.Future;
        }
        else if (currDate <= DayDeath2)
        {
            week.WeekType = WeekType.PossibleFuture;
        }

        lstItem.Weeks.Add(week);
        currDate = currDate.AddDays(7);
    }
}

填充效果很好(尽管需要一些调整): 在此处输入图像描述

XAML中还有一个workshop解决了部分问题:

<Window.Resources>
    <Style TargetType="ColumnDefinition" x:Key="lifecol" >
        <Setter Property="SharedSizeGroup" Value="A"/>
        <Setter Property="Width" Value="30"/>
    </Style>
    <Style TargetType="RowDefinition" x:Key="liferow" >
        <Setter Property="SharedSizeGroup" Value="A"/>
        <Setter Property="Height" Value="20"/>
    </Style>
</Window.Resources>

<ListBox Grid.Row="2" Name="lifeControlWrapper" Background="AliceBlue" ItemsSource="{Binding Life}">   
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
                        <ColumnDefinition/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="20"/>
                    </Grid.RowDefinitions>
                    <TextBlock Text="{Binding YearsAbsolute}" VerticalAlignment="Center"  Grid.Column="0"/>
                    <TextBlock Text="{Binding YearsRelative}" VerticalAlignment="Center" HorizontalAlignment="Right"  Grid.Column="1"/>
                    <Grid  Grid.Column="2" HorizontalAlignment="Stretch" Grid.IsSharedSizeScope="True">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition  Style="{StaticResource lifecol}"/>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Style="{StaticResource liferow}"/>
                        </Grid.RowDefinitions>
                        <Button Name="brnFirst"  Width="auto" Margin="2" Grid.Column="0" Height="{Binding ElementName=brnFirst, Path=Width}"></Button>
                        <Button Width="auto" Margin="2" Grid.Column="1"></Button>
                    </Grid>
                </Grid>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

结果应该是这样的: 在此处输入图像描述

更详细的结果示例

同时,我希望能够与窗口一起缩放,并且单元格将同时保持方形(部分实现)

问题:

  1. 如何根据Life每个“周”的按钮输出中生成的数据来执行此操作?不要为一年中的每个星期写一个按钮?(行)以便您可以通过绑定手动显示它?
  2. 如何每 5 个单元格缩进一次?(垂直和水平)
  3. 如何根据 WeekType 更改按钮颜色?
  4. 如何根据某些框架中的窗口大小自动更改年数的字体?

……

简而言之,鉴于我想在使用 WPF 方面正确地完成所有工作,而不仅仅是这样做,如何实现图片中的结果。

我们需要代码+解释为什么这样做/为什么这种方法是正确的。没有狂热的咀嚼。但仅限于主要思想。

c#
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Андрей NOP
    2020-01-16T14:58:13Z2020-01-16T14:58:13Z

    在您的布局中,基本尺寸是日历单元格的尺寸,标题的尺寸取决于它。由于我想不出一种优雅的方法将测量单元格大小的结果从位于模板中的面板转发到ItemsControl外部,我们将做相反的事情 - 我们将从外部计算单元格大小并将其传递给日历本身的面板及其标题面板。奖励 - 您可以为日历及其标题使用相同的面板。

    因此,让我们将一个无害的放入窗口的根 Grid 中,ContentControl并使用转换器将Tag单元格大小写入其大小。

    我对转换器有这样的空白:

    abstract class MultiConverterBase : MarkupExtension, IMultiValueConverter
    {
        public abstract object Convert(object[] values, Type targetType, object parameter, CultureInfo culture);
        public virtual object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
            => throw new NotImplementedException();
        public override object ProvideValue(IServiceProvider serviceProvider) => this;
    }
    

    它实现MarkupExtension了 ,因此在标记中使用它更方便一些 - 无需创建额外的资源。所以转换器:

    class SplitGridCellLengthConverter : MultiConverterBase
    {
        public override object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            var totalLength = (double)values[0];
            var cells = (int)values[1];
            var shortSpace = (double)values[2];
            var longSpace = (double)values[3];
            var longSpacePeriod = (int)values[4];
            var totalNum = Math.Max(cells - 1, 0);
            var longNum = totalNum / longSpacePeriod;
            var shortNum = totalNum - longNum;
            var totalSpace = longNum * longSpace + shortNum * shortSpace;
            return Math.Max(totalLength - totalSpace, 0) / cells;
        }
    }
    

    我们将需要一些常量,比如日历中的列数和其他东西,也许你会在 VM 中拥有它们,但我也使用了一堆标记扩展:

    class ValueExtension<T> : MarkupExtension
    {
        public T Value { get; set; }
        public ValueExtension() { }
        public ValueExtension(T value) => Value = value;
        public override object ProvideValue(IServiceProvider serviceProvider) => Value;
    }
    
    class IntExtension : ValueExtension<int>
    {
        public IntExtension() { }
        public IntExtension(int value) : base(value) { }
    }
    
    class DoubleExtension : ValueExtension<double>
    {
        public DoubleExtension() { }
        public DoubleExtension(double value) : base(value) { }
    }
    

    现在我们写:

    <Grid Margin="5">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
    
        <ContentControl Name="CellLengthHelper" Grid.Row="1" Grid.Column="1">
            <ContentControl.Tag>
                <MultiBinding Converter="{c:SplitGridCellLengthConverter}">
                    <Binding RelativeSource="{RelativeSource Self}" Path="ActualWidth"/>
                    <Binding Source="{c:Int 53}"/>
                    <Binding Source="{c:Double 2}"/>
                    <Binding Source="{c:Double 5}"/>
                    <Binding Source="{c:Int 5}"/>
                </MultiBinding>
            </ContentControl.Tag>
        </ContentControl>
    </Grid>
    

    现在我们有了单元格大小,我们可以将其用作日历单元格(正方形)的高度和宽度,以及行标题的高度和列标题的宽度

    现在我们正在编写一个面板,它将其元素放置在具有大小缩进的相同大小的单元格中:

    public class SplitGrid : Panel
    {
        #region AP
        public static int GetColumn(DependencyObject obj)
            => (int)obj.GetValue(ColumnProperty);
    
        public static void SetColumn(DependencyObject obj, int value)
            => obj.SetValue(ColumnProperty, value);
    
        public static readonly DependencyProperty ColumnProperty =
            DependencyProperty.RegisterAttached("Column", typeof(int),
                typeof(SplitGrid), new PropertyMetadata(0));
    
        public static int GetRow(DependencyObject obj)
            => (int)obj.GetValue(RowProperty);
    
        public static void SetRow(DependencyObject obj, int value)
            => obj.SetValue(RowProperty, value);
    
        public static readonly DependencyProperty RowProperty =
            DependencyProperty.RegisterAttached("Row", typeof(int),
                typeof(SplitGrid), new PropertyMetadata(0));
        #endregion AP
    
        #region DP
        public int Columns
        {
            get => (int)GetValue(ColumnsProperty);
            set => SetValue(ColumnsProperty, value);
        }
    
        public static readonly DependencyProperty ColumnsProperty =
            DependencyProperty.Register(nameof(Columns), typeof(int), typeof(SplitGrid),
                new FrameworkPropertyMetadata(1, FrameworkPropertyMetadataOptions.AffectsMeasure), ValidateColumns);
    
        private static bool ValidateColumns(object value) => (int)value > 0;
    
        public int Rows
        {
            get => (int)GetValue(RowsProperty);
            set => SetValue(RowsProperty, value);
        }
    
        public static readonly DependencyProperty RowsProperty =
            DependencyProperty.Register(nameof(Rows), typeof(int), typeof(SplitGrid),
                new FrameworkPropertyMetadata(1, FrameworkPropertyMetadataOptions.AffectsMeasure), ValidateRows);
    
        private static bool ValidateRows(object value) => (int)value > 0;
    
        public double ShortSpace
        {
            get => (double)GetValue(ShortSpaceProperty);
            set => SetValue(ShortSpaceProperty, value);
        }
    
        public static readonly DependencyProperty ShortSpaceProperty =
            DependencyProperty.Register(nameof(ShortSpace), typeof(double), typeof(SplitGrid),
                new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsMeasure));
    
        public double LongSpace
        {
            get => (double)GetValue(LongSpaceProperty);
            set => SetValue(LongSpaceProperty, value);
        }
    
        public static readonly DependencyProperty LongSpaceProperty =
            DependencyProperty.Register(nameof(LongSpace), typeof(double), typeof(SplitGrid),
                new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.AffectsMeasure));
    
        public int LongSpacePeriod
        {
            get { return (int)GetValue(LongSpacePeriodProperty); }
            set { SetValue(LongSpacePeriodProperty, value); }
        }
    
        public static readonly DependencyProperty LongSpacePeriodProperty =
            DependencyProperty.Register(nameof(LongSpacePeriod), typeof(int), typeof(SplitGrid),
                new FrameworkPropertyMetadata(5, FrameworkPropertyMetadataOptions.AffectsMeasure), ValidateLongSpacePeriod);
    
        private static bool ValidateLongSpacePeriod(object value) => (int)value > 0;
    
        public double CellWidth
        {
            get => (double)GetValue(CellWidthProperty);
            set => SetValue(CellWidthProperty, value);
        }
    
        public static readonly DependencyProperty CellWidthProperty =
            DependencyProperty.Register(nameof(CellWidth), typeof(double), typeof(SplitGrid),
                new FrameworkPropertyMetadata(double.PositiveInfinity, FrameworkPropertyMetadataOptions.AffectsMeasure));
    
        public double CellHeight
        {
            get => (double)GetValue(CellHeightProperty);
            set => SetValue(CellHeightProperty, value);
        }
    
        public static readonly DependencyProperty CellHeightProperty =
            DependencyProperty.Register(nameof(CellHeight), typeof(double), typeof(SplitGrid),
                new FrameworkPropertyMetadata(double.PositiveInfinity, FrameworkPropertyMetadataOptions.AffectsMeasure));
        #endregion DP
    
        // Этап подсчета занимаемого места
        protected override Size MeasureOverride(Size constraint)
        {
            columns = Columns;
            rows = Rows;
            shortSpace = ShortSpace;
            longSpace = LongSpace;
            longSpacePeriod = LongSpacePeriod;
            cellWidth = CellWidth;
            cellHeight = CellHeight;
            var cellSize = new Size(cellWidth, cellHeight);
    
            // Обязанность панели запросить желаемое место элементов
            foreach (UIElement child in InternalChildren)
                child.Measure(cellSize);
    
            // Если размеры ячейки не заданы, выбираем размер наибольшего элемента
            if (double.IsInfinity(cellWidth))
                cellWidth = InternalChildren.Cast<UIElement>().Max(child => child.DesiredSize.Width);
            if (double.IsInfinity(cellHeight))
                cellHeight = InternalChildren.Cast<UIElement>().Max(child => child.DesiredSize.Height);
    
            // Итоговые желаемые размеры панели
            double width = CalcTotalSpace(columns - 1) + columns * cellWidth;
            double height = CalcTotalSpace(rows - 1) + rows * cellHeight;
            return new Size(width, height);
        }
    
        // Этап размещения элементов
        protected override Size ArrangeOverride(Size arrangeSize)
        {
            foreach (UIElement child in InternalChildren)
            {
                int column = GetColumn(child);
                int row = GetRow(child);
                double x = column * cellWidth + CalcTotalSpace(column);
                double y = row * cellHeight + CalcTotalSpace(row);
                var childBounds = new Rect(x, y, cellWidth, cellHeight);
                // Размещаем
                child.Arrange(childBounds);
            }
    
            double width = CalcTotalSpace(columns - 1) + columns * cellWidth;
            double height = CalcTotalSpace(rows - 1) + rows * cellHeight;
            return new Size(width, height);
        }
    
        private int columns;
        private int rows;
        private double shortSpace;
        private double longSpace;
        private int longSpacePeriod;
        private double cellWidth;
        private double cellHeight;
    
        private double CalcTotalSpace(int totalNum)
        {
            if (totalNum < 0) return 0;
            int longNum = totalNum / longSpacePeriod;
            int shortNum = totalNum - longNum;
            return longNum * longSpace + shortNum * shortSpace;
        }
    }
    

    测试。虚拟机:

    class MainVm : Vm
    {
        public List<WeekVm> Weeks { get; } = new List<WeekVm>();
    
        public MainVm()
        {
            // Считаем что неделя относится к тому году,
            //  к которому относится понедельник
            var date = new DateTime(2000, 1, 1);
            while (date.DayOfWeek != DayOfWeek.Monday)
                date = date.AddDays(1);
            var endDate = new DateTime(2010, 1, 1);
            int weekNum = 0;
            while (date < endDate)
            {
                int year = date.Year;
                var week = new WeekVm(year - 2000, weekNum);
                Weeks.Add(week);
                date = date.AddDays(7);
                if (date.Year > year) weekNum = 0;
                else weekNum++;
            }
        }
    }
    
    class WeekVm : Vm
    {
        public int YearNum { get; }
        public int WeekNum { get; }
    
        public WeekVm(int yearNum, int weekNum)
        {
            YearNum = yearNum;
            WeekNum = weekNum;
        }
    }
    

    添加到根网格:

        <ItemsControl ItemsSource="{Binding Weeks}" VerticalAlignment="Top" Grid.Row="1" Grid.Column="1">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <c:SplitGrid Columns="53" Rows="10" ShortSpace="2" LongSpace="5" LongSpacePeriod="5"
                                 CellWidth="{Binding Tag, ElementName=CellLengthHelper}"
                                 CellHeight="{Binding Tag, ElementName=CellLengthHelper}"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemContainerStyle>
                <Style TargetType="ContentPresenter">
                    <Setter Property="c:SplitGrid.Column" Value="{Binding WeekNum}"/>
                    <Setter Property="c:SplitGrid.Row" Value="{Binding YearNum}"/>
                </Style>
            </ItemsControl.ItemContainerStyle>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Border BorderBrush="Gray" BorderThickness="1"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    

    我们推出:

    在此处输入图像描述

    现在是头条新闻。我从这里得到了这个想法,写了一个这样的类来在视图端显示标题:

    class HeaderItem
    {
        public int Index { get; }
        public string Text { get; }
        public HeaderItem(int index, string text)
        {
            Index = index;
            Text = text;
        }
    }
    

    这样的转换器将为我们生成一个列表HeaderItem:

    class HeaderListConverter : MultiConverterBase
    {
        public override object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            var start = (int)values[0];
            var count = (int)values[1];
            var delta = (int)values[2];
            var headerList = Enumerable
                                .Range(start, count)
                                .Where(h => h % 5 == 0)
                                .Select(h => new HeaderItem(h - delta, $"{h}"));
            return headerList;
        }
    }
    

    我们在根内部使用Grid:

        <ItemsControl Grid.Column="1">
            <ItemsControl.ItemsSource>
                <MultiBinding Converter="{c:HeaderListConverter}">
                    <Binding Source="{c:Int 1}"/>
                    <Binding Source="{c:Int 53}"/>
                    <Binding Source="{c:Int 1}"/>
                </MultiBinding>
            </ItemsControl.ItemsSource>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <c:SplitGrid Columns="53" ShortSpace="2" LongSpace="5" LongSpacePeriod="5"
                                 CellWidth="{Binding Tag, ElementName=CellLengthHelper}"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemContainerStyle>
                <Style TargetType="ContentPresenter">
                    <Setter Property="c:SplitGrid.Column" Value="{Binding Index}"/>
                    <Setter Property="Margin" Value="-20,0,0,0"/>
                    <Setter Property="HorizontalAlignment" Value="Right"/>
                </Style>
            </ItemsControl.ItemContainerStyle>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Text}" FontSize="{Binding Tag, ElementName=CellLengthHelper}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    
        <ItemsControl Grid.Row="1" VerticalAlignment="Top">
            <ItemsControl.ItemsSource>
                <MultiBinding Converter="{c:HeaderListConverter}">
                    <Binding Source="{c:Int 0}"/>
                    <Binding Source="{c:Int 10}"/>
                    <Binding Source="{c:Int 0}"/>
                </MultiBinding>
            </ItemsControl.ItemsSource>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <c:SplitGrid Rows="10" ShortSpace="2" LongSpace="5" LongSpacePeriod="5"
                                 CellHeight="{Binding Tag, ElementName=CellLengthHelper}"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemContainerStyle>
                <Style TargetType="ContentPresenter">
                    <Setter Property="c:SplitGrid.Row" Value="{Binding Index}"/>
                    <Setter Property="Margin" Value="0,-10,2,-10"/>
                    <Setter Property="HorizontalAlignment" Value="Right"/>
                    <Setter Property="VerticalAlignment" Value="Center"/>
                </Style>
            </ItemsControl.ItemContainerStyle>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Text}" FontSize="{Binding Tag, ElementName=CellLengthHelper}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    

    在此处输入图像描述

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

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

    Я написал немного кода для перехвата сообщений и выставления простой текстовой заглушки вместо контента окна:

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    
        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);
            HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
            source.AddHook(WndProc);
        }
    
        private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            switch (msg)
            {
                case 0x0231: // WM_ENTERSIZEMOVE
                    content = Content;
                    Content = new TextBlock
                    {
                        Text = "Обновление...",
                        HorizontalAlignment = HorizontalAlignment.Center,
                        VerticalAlignment = VerticalAlignment.Center
                    };
                    break;
                case 0x0232: // WM_EXITSIZEMOVE
                    Content = content;
                    break;
            }
            return IntPtr.Zero;
        }
    
        private object content;
    }
    

    您可以改为在窗口中公开一个 DP,并在标记中对其进行触发器并输出一些更具吸引力的存根。

    未完待续...

    GitHub上项目的存储库:WpfSplitGrid

    • 6

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    根据浏览器窗口的大小调整背景图案的大小

    • 2 个回答
  • Marko Smith

    理解for循环的执行逻辑

    • 1 个回答
  • Marko Smith

    复制动态数组时出错(C++)

    • 1 个回答
  • Marko Smith

    Or and If,elif,else 构造[重复]

    • 1 个回答
  • Marko Smith

    如何构建支持 x64 的 APK

    • 1 个回答
  • Marko Smith

    如何使按钮的输入宽度?

    • 2 个回答
  • Marko Smith

    如何显示对象变量的名称?

    • 3 个回答
  • Marko Smith

    如何循环一个函数?

    • 1 个回答
  • Marko Smith

    LOWORD 宏有什么作用?

    • 2 个回答
  • Marko Smith

    从字符串的开头删除直到并包括一个字符

    • 2 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5