Ответы пользователя по тегу WPF
  • Как получить доступ к динамически созданным c помощью datatemplate объектам в xaml?

    lam0x86
    @lam0x86
    Не надо получать доступ к TextBox-ам, это нарушает принцип MVVM (хотя и возможно через хаки типа обхода визуального дерева). К тому же, при режиме
    VirtualizingStackPanel.VirtualizationMode="Recycling"
    (который используется по умолчанию) не всем элементам массива ParameterList будут соответствовать TextBox-ы.

    Предполагается что данные в этих textbox будут меняться и передаваться дальше.

    Вот тут не понял. Что значит передаваться дальше?
    Ответ написан
  • Как правильно разметить окно в WPF разметке?

    lam0x86
    @lam0x86
    У тех колонок/строк, в которых находятся элементы с фиксированным размером, нужно проставить Auto в свойствах Width/Height.

    <RowDefinition Height="Auto"></RowDefinition>
    <ColumnDefinition Width="Auto"></RowDefinition>
    Ответ написан
    Комментировать
  • Binding StringFormat (WPF) не срабатывает?

    lam0x86
    @lam0x86
    <Label
      Content="{Binding ElementName=slider1, Path=Value}"
      ContentStringFormat="{}Выбрано {0} единиц"
      DockPanel.Dock="Top"
    />
    Ответ написан
    1 комментарий
  • Как оптимизировать код?

    lam0x86
    @lam0x86
    Почему бы не задать гриду коллекцию Task-ов в качестве ItemsSource?
    Ответ написан
    3 комментария
  • Почему искажаются линии при рисовании в WPF?

    lam0x86
    @lam0x86
    Надо поставить свойство StrokeLineJoin в Bevel.
    Ответ написан
    Комментировать
  • Как пробросить свойство из контрола WPF?

    lam0x86
    @lam0x86
    Во-первых, надо использовать TemplateBinding (ведь вы темплейт переопределили для своего контрола?)
    Во-вторых, в метадате нельзя писать "new ObservableCollection()", т.к. все ваши контроллы будут ссылаться на одну и ту же коллекцию.
    Ответ написан
    Комментировать
  • Что я делаю не так при создании свойства зависимости в wpf?

    lam0x86
    @lam0x86
    Скорее всего, canvas1.Background у вас равен Brushes.White. Это синглтон, и он находится в состоянии Frozen (свойство IsFrozen == true), то есть его нельзя менять. Попробуйте указать "#FFFFFF" вместо "White".
    Ответ написан
    3 комментария
  • Как использовать DependencyProperty?

    lam0x86
    @lam0x86
    Напишите конвертер, который будет реализовывать IMultiValueConverter и перемножать то, что приходит к нему на вход. В xaml-е у secondBox-а определите байндинг не атрибутом, а внутренним элементом, указав в качестве конвертера свою реализацию и внутренние привязки.
    Ответ написан
  • WPF. Какие элементы использовать в мессенджер-приложении?

    lam0x86
    @lam0x86
    Grid явно не подходит в силу отсутствия виртуализации. ListBox на первых порах подойдёт, но затем, скорее всего, вы всё-равно столкнётесь с его ограничениями - он поддерживает только визуальную виртуализацию, но не виртуализацию данных. Скажем, чат из 100 сообщений будет летать, но если вы планируете делать поддержку групповых чатов и с бесконечной историей, то есть вероятность, что приложение будет неотзывчивым уже начиная с 1000 сообщений истории.
    В общем, до этого надо еще дожить. Скорее всего, хватит ListBox (или ListView) как для списка чатов, так и для самих чатов. Идею с Grid-ом советую сразу отбросить - хотя бы из-за прожорливости в плане оперативки.
    Ответ написан
    4 комментария
  • Как определить что элемент в рабочей области?

    lam0x86
    @lam0x86
    Вообще, в WPF с виртуализацией данных всё довольно печально. Из-за её отсутствия и расплодилось такое количество сторонних гридов. Но тем не менее, можно подписаться на события ItemContainerGenerator-а, который отвечает за визуальную виртуализацию, и подгружать данные во время появления контейнера строк на экране.
    Ответ написан
    Комментировать
  • Как восстановить xaml из baml?

    lam0x86
    @lam0x86
    На сколько я понял из приведенного кода, нужно писать так:
    <Window x:Class="ссылка на класс Login" ...>
    ...
    </Window>
    Ответ написан
  • Как правильно информировать о процессе выполнения задачи?

    lam0x86
    @lam0x86
    Пробовал через класс Progress, но тут мне не понравилось плодить большое кол во классов через
    Progress.Report(new MyReport{...});

    Ничего страшного в этом нет - эти объекты на самом деле тут же умирают, не покидая первого поколения GC.
    Тут другой вопрос более важен: класс Progress устроен так, что маршаллит все репорты в SynchronizationContext, в котором он был создан. В случае с WinForms - это контекст UI-потока. Если ваш Task слишком часто будет вызывать метод Report, это может негативно сказаться на UI-потоке, т.к. он будет забит репортами, каждый из которых он должен обработать. Более того, поскольку маршаллинг в классе Progress асинхронный, есть вероятность, что задача будет выполнена до того, как на UI-потоке обработаются все репорты. Получется запаздывание прогресс-бара от реального прогресса (и вот тут как раз возникает вероятность перехода репортов в Gen1 и Gen2).

    Я бы написал свою реализацию класса Progress, которая использует таймер, периодически опрашивающий последнее обновление прогресса. Так сделано в большинстве систем, где обновление может происходить часто, например, при копировании множества файлов. Примерно так:

    public interface IProgressInfo
        {
            bool IsCompleted { get; }
        }
    
        public class ProgressInfo : IProgressInfo
        {
            public ProgressInfo(double completedPercentage, string progressStatusText)
            {
                CompletedPercentage = completedPercentage;
                ProgressStatusText = progressStatusText;
            }
    
            public double CompletedPercentage { get; private set; }
    
            public string ProgressStatusText { get; private set; }
    
            public bool IsCompleted
            {
                get { return CompletedPercentage >= 1; }
            }
        }
    
        public class Progress<T> : IProgress<T> where T : class, IProgressInfo
        {
            private T _previousProgressInfo;
            private volatile T _progressInfo;
            private readonly Action<T> _updateProgressAction;
            private readonly Timer _timer;
            private readonly SynchronizationContext _synchronizationContext;
    
            public Progress(TimeSpan pollingInterval, Action<T> updateProgressAction)
            {
                _synchronizationContext = SynchronizationContext.Current ?? new SynchronizationContext();
                _updateProgressAction = updateProgressAction;
                _timer = new Timer(TimerCallback, null, pollingInterval, pollingInterval);
            }
    
            private void TimerCallback(object state)
            {
                ProcessUpdate();
            }
    
            private void ProcessUpdate()
            {
                var progressInfo = _progressInfo;
                if (_previousProgressInfo != progressInfo)
                {
                    _synchronizationContext.Send(state => _updateProgressAction((T) state), progressInfo);
                }
                _previousProgressInfo = progressInfo;
            }
    
            public void Report(T value)
            {
                _progressInfo = value;
                if (value.IsCompleted)
                {
                    _timer.Dispose();
                    ProcessUpdate();
                }
            }
        }


    Использовать его можно примерно так:

    var workClass = new WorkClass();
    
                var list = Enumerable.Range(1, 1000).Select(i => i.ToString()).ToArray();
                var progress = new Progress<ProgressInfo>(TimeSpan.FromMilliseconds(100), UpdateProgressAction);
    
                await workClass.LongMethod(list, progress);


    где:

    private void UpdateProgressAction(ProgressInfo obj)
            {
                ProgressBar.Value = obj.CompletedPercentage;
                OperationStatus.Text = obj.ProgressStatusText;
                ProgressBarPercentage.Text = string.Format("{0:P}", obj.CompletedPercentage);
            }
    
    internal class WorkClass
        {
            public async Task LongMethod(IReadOnlyList<string> something, IProgress<ProgressInfo> progress)
            {
                await Task.Factory.StartNew(() =>
                {
                    var count = something.Count;
                    for (int i = 0; i < count; i++)
                    {
                        var element = something[i];
                        Thread.Sleep(5);
                        progress.Report(new ProgressInfo((double)(i + 1) / count, element));
                    }
                });
            }
        }
    Ответ написан
    3 комментария
  • Какие посмотреть образцовые open-source проекты на WPF?

    lam0x86
    @lam0x86
    Я бы посоветовал почитать про Prism: msdn.microsoft.com/en-us/library/gg406140.aspx
    Хоть это и не готовое приложение, но из документации можно почерпнуть много полезных шаблонов, которые применяются в разработке под WPF.
    Ответ написан
  • Как поменять свойство родительского контрола?

    lam0x86
    @lam0x86
    Я бы попробовал использовать TextBox вместо TextBlock:

    <TextBox TextWrapping="Wrap"
             VerticalScrollBarVisibility="Auto"
             IsReadOnly="True"
             Cursor="Arrow"
             Focusable="False"
             BorderThickness="0"
             Text="{Binding FirstInformation}"/>


    И ScrollViewer не нужен в этом случае.
    Ответ написан
    Комментировать