Задать вопрос
  • Как сделать анимированное переключение изображений в WPF?

    @i_light
    Backend, XAML, crossplatform
    Используйте триггеры:

    В XAML:
    <Image Source="{Binding CurrentImage}" >
        <Image.Triggers>
            <EventTrigger RoutedEvent="Image.Loaded">
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetProperty="(Image.Opacity)" From="0" To="1" Duration="0:0:1" />
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Image.Triggers>
    </Image>
    
    <Button Content="Next image" MouseLeftButtonDown="NextImageClick"/>


    В классе модели:

    public BitmapImage CurrentImage { get; set; }
    
    public List<BitmapImage> Images { get; set; }
    
    private int _imageIndex = 0;
    
    public void NextImageClick(object sender, MouseButtonEventArgs e)
    {
       if (_imageIndex >= Images.Count) _imageIndex = 0;
       CurrentImage = Images[imageIndex];
       RaisePropertyChanged("CurrentImage");  //необходимо реализовать INotifyPropertyChanged в классе модели
       _imageIndex++;
    }


    Должно сработать :)

    При надобности, анимацию можно сделать любую другую.
    Ответ написан
    Комментировать
  • Как запустить Task после его выполнения?

    @mayorovp
    Я немного не понял, вам надо запускать задачи последовательно или параллельно? А если параллельно - то обрабатывать результаты сразу или вместе?

    1. Последовательный запуск:
    private async void OnlyLike()
    {
        for (var i=0; i<5; i++)
            TextBox.Text += await VK.NakrytkaLike(KeyAntigateTextBox.Text);
    }


    2. Параллельный запуск, обработка всех результатов вместе
    private async void OnlyLike()
    {
        var tasks = Enumerable.Range(0, 5).Select(i => VK.NakrytkaLike(KeyAntigateTextBox.Text));
        foreach (var result in await Task.WhenAll(tasks))
            TextBox.Text += result;
    }


    3. Параллельный запуск, обработка результатов сразу же:
    private async void OnlyLike()
    {
        TextBox.Text += await VK.NakrytkaLike(KeyAntigateTextBox.Text);
    }
    
    private void StartButton_Click(object sender, RoutedEventArgs e)
    {
        for (var i=0; i<5; i++)
            OnlyLike();
    }


    Выбирайте что нравится. И не бойтесь использовать async/await - оно создано для упрощения кода, а не для усложнения :)

    UPD

    Последовательный запуск на фреймворке 4.0:
    public void OnlyLike()
    {
        var scheduler = TaskScheduler.Current ?? TaskScheduler.FromCurrentSynchronizationContext();
        Task task = TaskEx.FromResult(false);
        var text = KeyAntigateTextBox.Text;
        for (var i=0; i<5; i++) {
            task = task.ContinueWith(_ => {
                var LikeTurbo = VK.NakrytkaLike(text);
                LikeTurbo.ContinueWith(_ => {
                     TextBox.Text += LikeTurbo.Result;
                }, scheduler);
                return LikeTurbo;
            }, TaskContinuationOptions.ExecuteSynchronously).Unwrap();
        }
    }
    
    ...
    
    public static class TaskEx {
        public static Task<T> FromResult<T> (T result) {
            var tcs = new TaskCompletionSource<T>();
            tcs.SetResult(result);
            return tcs.Task;
        }
    
        public static Task<T> Unwrap<T>(this Task<Task<T>> task) {
            var tcs = new TaskCompletionSource<T>();
            task.ContinueWith(_ => {
                if (task.IsCanceled) tcs.SetCancelled();
                else if (task.IsFaulted) tcs.SetException(task.Exception);
                else task.Result.ContinueWith(innerTask => {
                    if (innerTask.IsCanceled) tcs.SetCancelled();
                    else if (innerTask.IsFaulted) tcs.SetException(task.Exception);
                    else tcs.SetResult(innerTask.Result);
                }, TaskContinuationOptions.ExecuteSynchronously);
            }, TaskContinuationOptions.ExecuteSynchronously);
            return tcs.Task;
        }
    }


    Выглядит многословно, но на самом деле - ничего сложного. В цикле задачи ставятся в очередь одна за другой при помощи конструкции task = task.ContinueWith(...).Unwrap(). Здесь Unwrap() - это функция, позволяющая дождаться выполнения дочерней задачи, фактически простой распаковщик монады Task Task T -> Task T.

    Внутри такого цикла находится, фактически, старый код метода OnlyLike() - за тем исключением, что теперь он еще и возвращает ту задачу, которую создал (это нужно, чтобы дождаться ее выполнения). Здесь я позволил себе небольшое ускорение - поскольку я написал return LikeTurbo - каждая следующая итерация цикла будет ждать лишь предыдущей задачи VK.NakrytkaLike - но не будет ждать вывода на экран предыдущих результатов. Если важно именно дождаться вывода результатов - то надо возвращать не LikeTurbo, а результат ContinueWith.

    Также тут очень важно расположение вызова TaskScheduler.FromCurrentSynchronizationContext(); Поскольку в момент исполнения прошлой задачи мы можем находиться в любом контексте - то ориентироваться на текущий контекст нельзя. Нужный нам планировщик задач следует сохранить при входе в метод (на будущее: его нужно _всегда_ сохранять _только_ при входе в метод!)
    Ответ написан
  • Как сделать динамический список CheckBox в WPF ?

    @Sumor
    В простейшем случае это должно выглядеть где-то так:
    XAML:
    <ListBox x:Name="lst">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <CheckBox Content="{Binding Value}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

    В коде, например:
    lst.ItemsSource = new List<KeyValuePair<int, string>>()
    {
        new KeyValuePair<int, string>(1, "1"),
        new KeyValuePair<int, string>(2, "2"),
    };

    Данный код покажет вам ваш список с чекбоксиками. К чекбоксу можно привязать событие на изменение и отлавливать какой элемент зачекили или расчекили.
    При желании можно получить список отмеченных, но это не так тривиально.

    Лучше использовать для отображения объект у которого есть логическое свойство, например IsChecked, и его привязать к IsChecked CheckBox.
    Например:
    Класс:
    class MyClass
    {
        public int id { get; set; }
        public string Name { get; set; }
        public bool IsChecked { get; set; }
    }

    XAML:
    <ListBox x:Name="lst">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <CheckBox Content="{Binding Name}" IsChecked="{Binding IsChecked}"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

    Добавление элементов:
    lst.ItemsSource = new List<MyClass>()
    {
        new MyClass(){id=1, Name="1"},
        new MyClass(){id=2, Name="2"},
    };

    В таком случае отметка пользователем галочки сразу отражается в привязанном списке и можно легко получить список отмеченных:
    foreach(var tObj in (lst.ItemsSource as List<MyClass>).Where(myObj => myObj.IsChecked))
        MessageBox.Show(tObj.Name);
    Ответ написан
    2 комментария
  • Есть ли сервисы, предлагающие клавиатуры с более чем с 105-ю клавишами и собственными надписями на них?

    Informatikum
    @Informatikum
    Преподаю робототехнику и информатику в школе.
    Делаю свой проект, не стандартную клаву. Если получится, через год смогу помочь вам с клавой. :)
    Ответ написан
    Комментировать
  • Почему приложение на C# съедает в 5 раз больше ожидаемого объема памяти?

    vipuhoff
    @vipuhoff
    Для проверки повставляй в каждом месте, которое выполняется больше 100 раз GC.Collect() и посмотри что получилось, если памяти съедать стал меньше значит где то не успевает собираться мусор. Потом можно по одному убирать то что повставлял и смотреть после какого память снова начала расти, в том месте и разбирайся, что то в нем не так.
    Ответ написан
    Комментировать
  • Почему приложение на C# съедает в 5 раз больше ожидаемого объема памяти?

    barkalov
    @barkalov
    Во "взрослой" студии есть анализ памяти - ANALIZE - Launch Perfomance Wizzard.
    Возможно, течет через замыкания. Или сборщик не поспевает, попробуйте GC.Collect().
    Ответ написан
    Комментировать
  • Почему в большинстве интерфейсов появление элементов плавное, а исчезание мгновенное?

    Если элемент плавно появляется и плавно исчезает, то при быстром проведении курсором, например, по пунктам меню вся менюшка начнет «скакать». Отсутствие анимации исчезания — один из вариантов избежания такого поведения.
    Ответ написан
    1 комментарий
  • Какие сборки и пространства имен должен знать хороший .NET программист?

    aush
    @aush
    У вас неправильное понимание ситуации. Я не думаю, что кто-то будет формулировать требование как "знать System.Collections.Generic". Но если вы не можете рассказать чем HashSet<T> отличается от List<T>, то это говорит о вашем опыте, что важно для работодателя.

    Вы хотите стать специалистом в web. В таком случае, чтобы выяснить объем ваших знаний, вам, скорее всего, будут задавать вопросы, для ответы на которые вам надо уметь работать с типами из System.Web. Но ставить себе задачу "выучить System.Web" - не очень продуктивно.
    Ответ написан
    2 комментария
  • Возможно ли путь к подключаемой dll вынести в какой-нибудь внешний файл?

    @Sumor
    Неуправляемую dll можно подгружать динамически через LoadLibrary, указывая к ней путь.
    Порядок примерно такой:
    1. LoadLibrary с путём к dll.
    2. GetProcAddress получает неуправляемый указатель на функцию в dll.
    3. Marshal.GetDelegateForFunctionPointer преобразует неуправляемый указатель на функцию в делегата, который можно использовать обычным для c# способом.
    4. FreeLibrary завершает работу с dll.

    Подробнее и с примером

    Ну а с управляемыми нужно работать через класс Assembly.
    Например, загрузка сборки — Assembly.LoadFrom(string)
    Ответ написан
    Комментировать
  • Java - тормозит, а Cи - нет?

    yaroslavkornilov
    @yaroslavkornilov
    https://taplink.cc/the.yaroslav.kornilov
    Что более тормозное русский или китайский язык? По - моему китайский, а китайцу кажется, что русский более тормозной.
    Теоретически С++ МОЖЕТ быть быстрее из-за того что он сразу "переводится" в машинный код, но это несет за собой уменьшение управляемости и скорости написания кода.
    Но в реальности расход ресурсов зависит от архитектуры программы и используемых алгоритмов.
    Поэтому однозначно сказать нельзя.
    Ответ написан
    Комментировать
  • Выбор профиля: C# или objective C?

    @beduin01
    Учите C#.
    Ответ написан
    Комментировать
  • Выбор профиля: C# или objective C?

    newross
    @newross
    Product owner
    C# + Xamarin - и можно писать на .Net для iOS и Android. Для бэкэнда C# + ServiceStack. В общем если душа лежит к платформе .Net - незачем от нее отказываться :)
    Ответ написан
    2 комментария
  • В чём разница dynamic vs Object в C#.NET?

    aush
    @aush
    Разница в том, что для dynamic вы можете написать
    dynamic myDinamic = GetDynamic();
    myDynamic.SomeMethod();


    Object же надо приводить в типу, для которого определен SomeMethod(), или использовать рефлексию. Т.е. проверка переносится с этапа компиляции на момент исполнения.
    Ответ написан
    1 комментарий
  • В чём разница dynamic vs Object в C#.NET?

    @gleb_kudr
    dynamic это тот же object, просто игнорирует все проверки на тип во время компиляции. Соответственно, вы можете попытаться вызывать у него любые методы и среда вам даст скомпилировать такую программу. Далее методы вызываются по сигнатуре (имя + типы аргументов). Если у динамического объекта вызвать метод с сигнатурой, отсутствующей в реальном объекте, который упакован в этом динамике, то выпадет исключение рантайма.

    Простой пример.

    class First{
    public First(){}
    public void test(string str){}
    }
    
    class Second{
    public Second(){}
    public void test(string str, int i){}
    }
    
    static void Main() 
    {
    dynamic myObj=new First();
    myObj.test("some string");//ok
    myObj=new Second();
    myObj.test("some string");// runtime error, требуется сигнатура test(string,int). То же самое будет если вызвать не существующий метод
    }


    Ответ на ваш вопрос: попытавшись то же самое сделать с object вы не сможете скомпилировать данную программу, вам нужно будет пользоваться приведением типов.

    Более того, если модифицировать пример так, чтобы методы test в разных классах имели одинаковую сигнатуру, то dynamic отработает вызов метода в любом случае. А приведение типа потребуется в каждом случае в свой класс, иначе возникнет ошибка.

    class First{
    public First(){}
    public void test(string str){}
    }
    
    class Second{
    public Second(){}
    public void test(string str){}
    }
    
    static void Main() 
    {
    object myObj=new First();
    (myObj as First).test("some string");//ok
    //myObj.test("some string"); такое не даст скомпилироваться
    myObj=new Second();
    (myObj as First).test("some string");// runtime error, требуется тип Second хотя сигнатура метода та же самая
    }
    Ответ написан
  • Зачем нужны методы доступа?

    @DancingOnWater
    @PokimonFromGamedev ты не совсем прав.

    Да, первые две причины действительно действуют именно так. Но в первом случаем мы объявляем просто метод, а вот втором проперти.

    Это не играет роли ровно до того момента, когда нужно производить связывание данных, а вот там это различие становится важным.
    Ответ написан
    Комментировать
  • Java - тормозит, а Cи - нет?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Программы на C/C++ работают быстрее за счёт отказа от контроля всего и вся (расхода памяти, переполнения стека, корректности указателей), за счёт явной и жёсткой типизации переменных, за счёт меньшего количества обёрток вокруг типов данных. Но это позволяет программисту выстрелить себе в ногу таким количеством способов, которые в Java и не снились.
    Ответ написан
    8 комментариев
  • WPF, работа с ListCollectionView в фоновом потоке - как исправить ошибку?

    MikhailD
    @MikhailD
    Developer
    Менять UI в потоках, отличных от UI-потока нельзя. Если вам нужно из другого потока изменить данные в UI, воспользуйтесь диспатчером

    Пример того, как это выглядит в WinRT:
    Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                    {
                        // Код, работающий в UI потоке
                    });
    Ответ написан
    Комментировать