Страницы

Поиск по вопросам

Показаны сообщения с ярлыком xaml. Показать все сообщения
Показаны сообщения с ярлыком xaml. Показать все сообщения

понедельник, 13 апреля 2020 г.

SilverLight XAML. Binding цвета эллипса к элементу массива цветов

#c_sharp #silverlight #xaml

                    
У меня есть эллипс, и вот такая конструкция:
private Brush lampColor;
public Brush LampColorTest
{
    get { return lampColor; }
    set
    {
        lampColor = value;
        OnPropertyChange("LampColorTest");
    }
}

С помощью какой-то команды я задаю LampColorTest значение, допустим, Yellow. Когда
это происходит, эллипс перекрашивается в желтый цвет. Привязываю эллипс я так:


Ответы

Ответ 1



Написать свой IValueConverter? public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { int index; if (!Int32.TryParse(parameter.ToString(), out index)) { // грязно ругаемся } var list = value as IList; if (list == null || list.Count < index + 1) { // аналогично } return list[index]; }

суббота, 11 апреля 2020 г.

Как сделать выпадающий список произвольной формы?

#wpf #xaml #style

                    
Здравствуйте, хотел бы узнать, как решить эту проблему. Есть элемент Expander, который
имеет свой стандартный стиль. Использование Data или Path даёт возможно изменить внешний
вид окна и саму кнопку для активации этого выпадающего списка при использование Template.
Как это возможно сделать и также чтобы выпадающий список был ровно под кнопкой? К примеру:
вызов окна в Skype Данные о качестве связи(громкость и тд.).



Note: знаю, как использовать  Data и Path.
    


Ответы

Ответ 1



Если надо можно будет дорисовать ^ самому, так как Path точно прорисован по контуру.

четверг, 9 апреля 2020 г.

Странная ошибка в XAML: ошибка при конвертации типа при присваивании через StaticResource

#c_sharp #wpf #xaml

                    
Не знал как коротко описать суть проблемы.

Вот код xaml


    
        
    
    
        
    



Вот код c# класса LocalizedString

public class LocalizedString : IComparable, ICloneable, IEnumerable, IEquatable,
IEquatable
{
    public LocalizedString(string str)
    {
        OriginalString = str;
    }

    public LocalizedString()
    {
        OriginalString = "";
    }

    public string OriginalString { get; set; }

    public string LocalizeString
    {
        get
        {
            return InteractiveLocalizer.Localize(OriginalString);
        }
    }

    public override string ToString()
    {
        return LocalizeString;
    }

    public int CompareTo(object obj)
    {
        if (obj == null)
            return 1;
        var str = obj as string;
        if (str != null)
            return LocalizeString.CompareTo(str);
        var lstr = obj as LocalizedString;
        if (lstr != null)
            return LocalizeString.CompareTo(lstr.LocalizeString);
        throw new ArgumentException("LocalizedDtring: Bad type");
    }

    public object Clone()
    {
        return new LocalizedString(OriginalString);
    }

    public IEnumerator GetEnumerator()
    {
        return LocalizeString.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public bool Equals(string other)
    {
        return other == LocalizeString || other == OriginalString;
    }

    public bool Equals(LocalizedString other)
    {
        return OriginalString == other.OriginalString;
    }

    public static implicit operator LocalizedString(string v)
    {
        return new LocalizedString(v);
    }

    public static explicit operator String(LocalizedString ls)
    {
        return ls.LocalizeString;
    }
}


В данном случае LocalizedString ворачивает ту же самую строку, что и получает "qwe".
Я это и ожидал, но во время выполнения прога падает с исключением. Вот текст 


  "qwe" не является допустимым значением для свойства "Text".


Как так? 

Ошибка есть и во время компиляции (хоть она и позволяет запуститься приложению).
Вот ее текст


  Не удается применить объект типа "LocalizerLib.LocalizedString" к
  свойству, для которого требуется тип "System.String".


В классе определены операторы implict и explict. Чего еще не хватает, чтобы я мог
вместо string вставить свой тип?
    


Ответы

Ответ 1



XAML игноирирует операторы приведения типа (хоть явные, хоть неявные). Разнообразные конвертеры используются, например, для преобразования результатов биндинга. И даже в этом случае операторы не используются, предпочтение отдаётся ассоциированному TypeConverter (который, впрочем, по умолчанию поддерживает преобразование к строке и просто вызывает ToString). Однако при использовании ресурсов никакой конвертации не производится. Ваш код приводит к вызову: object res = new LocalizedString("foo"); fooTextBlock.Text = res; С очевидными последствиями. Могу предложить несколько путей: Вместо странных костылей с ресурсами можно воспользоваться расширениями разметки MarkupExtension. Метод ProvideValue может возвращать произвольный тип и даже учитывать, какому свойству какого объекта значение сейчас присваивается. Выглядеть это в XAML будет кратко и естественно: Продолжать городить костыли, но заставить XAML вызвать конвертеры: Вообще-то в WPF встроены средства для локализации, но кому до них дело... P. S. Код не тестировал, мог наврать.

Как отобразить сферу с объектами в WPF?

#c_sharp #wpf #xaml

                    
Есть лист объектов с угловыми координатами (широта, долгота). Как мне можно показать
их наглядно на форме? Пытался уже что то сделать с ViewPort3D, но там рисовать сферу
придется по точкам и нормалям, а значит будет детализация. 

Мне пока приходит в голову использовать ListBox с Canvas в качестве панели, где будет
отрисован круг, на котором будут отображены проекции объектов (то есть псевдо-сфера).
Для начала хочу просто отобразить сферу с меридианами, которую я смогу вращать. По
идее все должно получиться, но я даже не знаю с чего мне начать.

UPD:

Если буду использовать ListBox или Selector для возможности выделения элементов,
то что делать с индексами? Хотелось бы, чтобы была зависимость между индексами и координатами
(ведь координаты - уникальный ключ). Так перебор элементов будет значительно быстрее.
Ну допустим тип double я смогу привести к целому числу, умножив его на число с нужным
количеством нулей (точность), но как быть со второй координатой. Их ведь две, а индекс
один. Как создать коллекцию с двойным индексом?
    


Ответы

Ответ 1



Всё очень просто. Вам нужно перевести сферические координаты (широту, долготу радиус) в трёхмерные. Затем умножением на матрицу поворота повернуть в нужное положение. Затем спроектировать на плоскость, отбросив одну координату, например, Y. При этом точки с положительной координатой Y находятся на противоположной стороне и их надо отбросить. Полученную картинку из квадрата [-R, R] линейно отобразите в квадрат координат экрана. Для обработки выделения я обычно использую не индексы, а вот такую конструкцию: VM: class Objects : NotifyPropertyChangeImpl { ObservableCollection All { get; private set; } // стандартное INPC-свойство ObjectVM selectedObject; public ObjectVM SelectedObject { get { return selectedObject; } set { if (value == selectedObject) return; value = selectedObject; NotifyPropertyChange(); } } } XAML:

Binding к this[enum] свойству экземпляра класса

#c_sharp #wpf #xaml #binding

                    
Есть enum

namespace namespace1.namespace2{
  enum PropertyObject 
  {
    A=1,
    B=2,
    ...
  }
}


и класс совершенно в другом namespace

public class MyClass
{
  public Object this[namespace1.namespace2.PropertyObject property]
  {
    get
    {
      return ...;
    }
  }
}


Список экземпляров всунут в ItemsSource ListView, есть также DataTemplate забитый
как ItemTemplate у ListView


  



я уверен, что данный PropertyObject у экземпяров установлен, однако пишет, что не
может достучаться до этого свойства, как создать валидный Binding к этим свойствам?

ошибка: System.Windows.Data Error: 40 : BindingExpression path error: '[]' property
not found on 'object' ''MyClass' (HashCode=55693485)'. BindingExpression:Path=this[namespace1.namespace2.PropertyObject.A];
DataItem='MyClass' (HashCode=55693485); target element is 'TextBlock' (Name=''); target
property is 'Text' (type 'String')
    


Ответы

Ответ 1



Вы используете неверный синтаксис для получения значения перечисления. В рамках XAML пространства имён в сборках (namespace в C#) и пространства имён в XML (xmlns в XML) задаются в шапке файла. При этом даже указание точного типа может не понадобиться: XAML достаточно умный, чтобы приобразовать строку к перечислению самостоятельно. Понятия "this" в биндингах тоже нет. Скорее всего, вам нужен или текущий контекст (Path='.' или просто Path=''), или текущий элемент (RelativeSource='{RelativeSource Self}' и прочие). Положим, у нас есть следующий код: namespace HakunaMatata { public partial class MainWindow { public MainWindow () { InitializeComponent(); DataContext = new Model(); } } public class Model { public string this [Other.Property prop] => prop.ToString() + " from Indexer"; } } namespace Other { public enum Property { Foo, Bar, } } Тогда все из способов обращения к индексатору будут работать корректно:

Ответ 2



Синтаксис Binding.Path - есть примеры разных привязок.

суббота, 4 апреля 2020 г.

Привязка команды к нажатию клавиши в TextBox

#c_sharp #wpf #xaml

                    
Есть текстовое поле и кнопочка рядом. Кнопочке назначена команда. В качестве параметра
передается текст текстового поля. Вопрос, а как ту же самую команду использовать для
текстового поля по нажатии клавиши Enter, например?
    


Ответы

Ответ 1



Нашел решение Точно так же можно привязываться к действиям мыши через MouseBinding.

четверг, 2 апреля 2020 г.

Create and used StaticResource Path in XAML code

#wpf #xaml #path #content

                    
Доброго времени суток.

Как можно заставить работать следующий код в XAML






Также, я пробовал так:






Но похоже это не работает
    


Ответы

Ответ 1



Все просто, нужно задать шаблон ContentTemplate:

понедельник, 30 марта 2020 г.

Пользовательские MarkupExtension в качестве ключа словаря

#c_sharp #wpf #net #xaml


К примеру, имеем такое расширение разметки:

using System;
using System.Windows.Markup;
namespace CustomMarkupExtensions
{
    public class HelloExtension : MarkupExtension
    {
        public HelloExtension() { }

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return "Hello";
        }
    }
}


Код XAML. Пытаюсь использовать расширение в качестве ключа в ResourceDictionary:



    Пример




При компиляции возникает ошибка:

(6,20): error MC3012: 
ключ словаря не может иметь тип "CustomMarkupExtensions.HelloExtension". 
Поддерживаются только типы String, TypeExtension и StaticExtension. Строка 6 позиция 20.


Хотя в описании директивы x:Key указано, что расширения разметки использоваться могут.
В чем дело?
    


Ответы

Ответ 1



В справке всё указано верно: в x:Key можно использовать расширения разметки, но только два: TypeExtension и StaticExtension. Пользовательские расширения разметки не поддерживаются, кроме наследников ResourceKey. (Также x:Key может содержать произвольное значение, но указать его можно только с помощью одного из перечисленных выше расширений разметки.) Это ограничение было снято в XAML 2009, вот только этот "стандарт" по сути не поддерживается. В XAML 2006, который, похоже, с нами навсегда, можно пойти обходным путём: положить значение в статическое свойство, затем указать его через x:Static.

воскресенье, 15 марта 2020 г.

Преобразование Bitmap ресурса в ImageSource

#c_sharp #wpf #xaml


Имеется Bitmap ресурс Properties.Resources.part1. Нужно установить этот ресурс в
свойство заполнения прямоугольника Rectangle.Fill. Но Fill свойство принимает только
тип ImageSource
    


Ответы

Ответ 1



Ваша задача имеет два решения: На одно @Mints97 привел ссылку Get ImageSource from Bitmap?, выглядит оно так: System.Drawing.Bitmap br = Properties.Resources.part1; System.Windows.Media.Imaging.BitmapSource b = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap( br.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); Но я бы не помещал рисунок в ресурсы, а поступил иначе: 1.Создал бы в проекте папку, например IMAGES; 2.Поместил ваш рисунок (part1) в эту папку; 3.Тогда бы код выглядел так: System.Windows.Media.Imaging.BitmapImage b = new BitmapImage( new Uri("pack://application:,,,/IMAGES/part1.bmp")); Ну и соответственно: rectangle.Fill = new ImageBrush(b);

Событие DragOver не приходит, при запуске программы под администратором

#c_sharp #wpf #xaml #drag_n_drop


Сделал GUI для серверной части системы, и начал было делать сам сервер, но при запуске
приложения от имени администратора событие DragOver тупо не вызывается.
При обычном запуске все ОК.

Для чистоты эксперимента создал новое решение, где с окном из такого кода:


    
        
    





private void UIElement_OnDragOver(object sender, DragEventArgs e)
{
    e.Effects = DragDropEffects.Copy;
}

private void UIElement_OnDrop(object sender, DragEventArgs e)
{
}


Результат тот же самый.
    


Ответы

Ответ 1



Это защита. UAC и всё такое. Если приложение, из которого производится перенос, имеет уровень доступа ниже, чем приложение, в которое переносится перенос, то операция запрещается на уровне операционной системы. Соответственно, нельзя перенести что-либо из приложения, запущенного под юзером, в приложение, запущенное под админом. А вот наоборот — можно. Код здесь совершенно не при чём. Вы можете запустить любое приложение, поддерживающее drag-n-drop, под админом, и убедиться, что на него нельзя ничего перенести из программ, запущенных не из-под админа. См. Q: Why Doesn’t Drag-and-Drop work when my Application is Running Elevated? – A: Mandatory Integrity Control and UIPI для более подробного объяснения. Если требуется перенос файлов, то существует костыль с ChangeWindowMessageFilterEx. См. How to enable drag and drop between normal & UAC elevated privileges applications.

Как убрать белый квадрат между вертикальным и горизонтальным ScrollBar?

#wpf #xaml #style


Здравствуйте, в собственном стиле образовался белый квадрат, который ни каким способом
не получается убрать, после того, как добавил Horizontal ScrollBar. Как заменить его
на конкретный цвет или картинку? Читал, что есть возможность его удалить и на том месте
будет использоваться стиль окна, но это может привести к непоправимым ошибкам. 

 

Возможно что-то было пропущено в коде:




TreeViewItem

     
            
                
                    
                
            
        


TreeView

       

    


Ответы

Ответ 1



Используя выше упомянутый TreeViewItem нужно дополнить строчкой после Border. Также нужно добавить такой код, который будет в сочетание с ScrollBar:

пятница, 13 марта 2020 г.

Обращение к определенному в XAML словарю ресурсов из застраничного кода

#c_sharp #xaml


У меня есть словарь ресурсов,определенный в XAML-разметке,например так:

    
some text
text


Как обратиться к такому словарю из  застраничного кода на C#(например,добавить несколько
элементов)?
    


Ответы

Ответ 1



Все, уже разобрался. Необходимо создать Uri, который будет указывать на нужный словарь и присвоить его свойству Sourse нового словаря ресурсов: Uri uri = new Uri(@"sample.xaml"); ResourceDictionary dict = new ResourceDictionary(); dict.Source = uri;`

Как сделать медленно плавающий фон?

#c_sharp #net #xaml #uwp


Как сделать эффект для image, чтобы, например, широкая картинка медленно плыла слева
направо, или сверху вниз?
    


Ответы

Ответ 1



Создаете анимацию для своей картинки И в удобном месте запускаете свою анимацию ImageMotionStoryboard.Begin(); UPDATE: пример работы

Как использовать индексаторы в xaml без квадратных скобок?

#c_sharp #net #wpf #xaml


Есть некий generic класс

public class GenericClass
{
    public object this[string s]
    {
        return s;
    }
}


Ну и экземпляр класса используется как DataContext. Тогда для вызова из xaml будет
такая разметка




и вернет она текст "qwer". 

Вопрос, а можно ли какими либо ухищрениями избавиться от квадратных скобок? Вот есть
класс DataView, как там это реализовано?
    


Ответы

Ответ 1



Нашел решение. Класс public class GenericClass должен наследовать интерфейс ICustomTypeDescriptor и индексатор в нем вообще не нужен. Тогда Мне нужно из конструктора просто подбирать передаваемый объект типа Т и использовать его как ресурс для реализации интерфейса. Я не выложу дословный код, потому что не имею его под рукой. Могу лишь из памяти набросать его основу Класс: public class ViewModel: ICustomTypeDescriptor { T _source; public ViewModel(T obj) { _source = obj; } // далее идет реализация интерфейса. Все методы сделаны идентично, я приведу пример одного public AttributeCollection GetAttributes() { return TypeDescriptor.GetAttributes(_source); } } Класс еще не готов. Нужно еще наследовать INotifyPropertyChanged и предусмотреть мониторинг свойств модели или иные способы изменения свойств из кода. Но это совсем другая история )

понедельник, 9 марта 2020 г.

Моргающее в панели задач окно

#c_sharp #wpf #xaml #mvvm


Подскажите пожалуйста как заставить окно моргать в панели задач? Ну так часто делают
типа какое то событие в окне произошло, а оно свернуто и вот такое извещение.

@VladD хз я может что то не так делаю, но у меня никак не хочет это работать. Я ставил
точку останова у меня при попытке создать экземпляр WindowInteropHelper выходит из
функции вообще. Тестирую вот так:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        var t = new Timer(5000);
        t.Elapsed += Elapsed;
        t.Start();
    }

    [DllImport("user32.dll")]
    public static extern int FlashWindow(IntPtr Hwnd, bool Revert);

    private void Elapsed(object sender, ElapsedEventArgs e)
    {
        var hwnd = new WindowInteropHelper(this).Handle;
        FlashWindow(hwnd, true);
    }
}

    


Ответы

Ответ 1



Попробуйте так: [DllImport("user32.dll")] public static extern int FlashWindow(IntPtr Hwnd, bool Revert); // ... var hwnd = new WindowInteropHelper(window).Handle; FlashWindow(hwnd, true); Вызывать эту функцию на таймере не стоит, т. к. он доставляет сообщения в непонятно какой поток. Используйте DispatcherTimer, он выполняет события в главном потоке: var dt = new DispatcherTimer(); dt.Tick += (s, e) => { dt.Stop(); var hwnd = new WindowInteropHelper(this).Handle; FlashWindow(hwnd, true); }; dt.Interval = TimeSpan.FromSeconds(5); dt.Start();

воскресенье, 8 марта 2020 г.

Проблема с DependencyProperty

#c_sharp #net #wpf #xaml


Такая ситуация. Есть класс

public partial class HighlightTextBlock : TextBlock
{
    public ObservableCollection HighlightRules
    {
        get { return (ObservableCollection)GetValue(HighlightRulesProperty); }
        set { SetValue(HighlightRulesProperty, value); }
    }

    // Using a DependencyProperty as the backing store for HighlightRules.  This
enables animation, styling, binding, etc...
    public static readonly DependencyProperty HighlightRulesProperty =
        DependencyProperty.Register("HighlightRules", typeof(ObservableCollection),
typeof(HighlightTextBlock), new FrameworkPropertyMetadata(new ObservableCollection()));

// Ну далее еще много чего тут
}


А вот класс HighlightRule

public class HighlightRule : DependencyObject
{
    public ObservableCollection Highlights
    {
        get { return (ObservableCollection)GetValue(HighlightsProperty); }
        set { SetValue(HighlightsProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Highlights.  This enables
animation, styling, binding, etc...
    public static readonly DependencyProperty HighlightsProperty =
        DependencyProperty.Register("Highlights", typeof(ObservableCollection),
typeof(HighlightRule), new PropertyMetadata(new ObservableCollection()));

// Тут тоже много чего еще
}


вот как выглядит использование в XAML


    
        
            
                
                    
                        
                            
                        
                    
                
            
        
    



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

UPD:

Вот проект по примеру VladD

скачать
    


Ответы

Ответ 1



Проблема вот где: new PropertyMetadata(new ObservableCollection()) У вас получается, что вы один и тот же экземпляр ObservableCollection делаете значением по умолчанию свойства Highlights для всех экземпляров HighlightRule! Обычно эта проблема незаметна, если ваше свойство — value type, т. к. он при копировании клонируется, в отличие от ссылочного типа. Делайте так: public class HighlightRule : DependencyObject { public HighlightRule() { Highlights = new ObservableCollection(); } public ObservableCollection Highlights { get { return (ObservableCollection)GetValue(HighlightsProperty); } set { SetValue(HighlightsProperty, value); } } public static readonly DependencyProperty HighlightsProperty = DependencyProperty.Register( "Highlights", typeof(ObservableCollection), typeof(HighlightRule)); // Тут тоже много чего еще } То же касается и HighlightTextBlock, разумеется.

пятница, 6 марта 2020 г.

WPF, DataGrid. Растягивание колонок при появлении свободного места

#c_sharp #wpf #xaml #datagrid


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




Вид при нехватке места:


Вид при избытке места:

    


Ответы

Ответ 1



Установите свойство ColumnWidth в *. Это приведет к равномерному растягиванию всех столбцов таблицы. Также в сочетании с этим свойством можете установить каким-то столбцам свою ширину. столбцы 2 и 3 поделят между собой всю свободную ширину, тем самым не будет видно "пустого столбца". UDP: Если таблица имеет фиксированную ширину то, для появления горизонтального скрола, можно сделать так:

среда, 4 марта 2020 г.

Настройка ToolTip для Combobox WPF

#c_sharp #wpf #xaml


Имеется коллекция объектов:

public class Param
{
    public string Name { get; set; }
    public string Description { get; set; }
}


Эту коллекцию необходимо привязать к ComboBox так, чтобы в качестве элемента списка
был Name, а в качестве всплываемой подсказки при наведении на каждый элемент был Description.
Это легко делается:


              
                
                    
                       
                                    
              
 


Все бы ничего, но как сделать так, чтобы когда Description null или пустой, ToolTip
вообще не отображался. Сейчас отображается пустой квадратик. Вариант ниже не помог.
Заранее спасибо.

                
                
                    
                        
                        
                                
                                    
                                        
                                    
                                    
                                        
                                    
                                
                            
                                              
                                        
                                                
            

    


Ответы

Ответ 1



У вас как-то сложно. Значение null должно убирать ToolTip и так, так что проблема только с пустой строкой. Проще всего просто отловить это через конвертер. class NullIfEmptyConverter : IValueConverter { public object Convert(object value, Type targetType, object p, CultureInfo ci) => (string)value == string.Empty ? null : value; public object ConvertBack(object value, Type targetType, object p, CultureInfo ci) => throw new NotSupportedException(); } (или, как подсказывает @Андрей в комментариях, string.IsNullOrWhiteSpace((string)value) ? null : value). Ваш код получается таким: Не забудьте положить в ресурсы окна

вторник, 25 февраля 2020 г.

Автоматическое растягивание элементов WPF под размер родителя (растягивание внутри ListBox)

#c_sharp #wpf #xaml


Есть ListBox выводящий список заказов

       
    
            
                
                    
                        
                        
                    
                    
                        
                    
                    
                        
                        
                        
                        
                        
                    
                    
                        


Ответы

Ответ 1



Задайте у ListBox свойство HorizontalContentAlignment: В шаблоне ListBoxItem выравнивание ContentPresenter определено через HorizontalContentAlignment родительского списка.

понедельник, 24 февраля 2020 г.

Анимация Transform в ControlTemplate

#wpf #xaml


Как анимировать ScaleTransform кнопки в шаблоне, и какой тип анимации необходимо
применить?
    


Ответы

Ответ 1



Вам нужно анимировать не всю трансформацию, а свойства ScaleX и ScaleY этой трансформации. Так как тип этих свойств double, соответственно, нужно использовать DoubleAnimation.