Windows Forms TreeView всегда выбирает узел на фокусе

1134 Я уже делал это раньше. Вот общее описание того, что я сделал:

  1. Поместите файлы мультиплатформенных значков в ваш проект .NetStandard как Embedded Resources . Это означает, что я нашел все различные разрешения, предоставленные Google (_xxhdpi, _xhdpi, _hdpi, _mdpi и т. Д.), А затем переименовал их в следующее:

    • icon@¾x.png
    • [ 1152] icon.png
    • icon@1½x.png
    • icon@2x.png
    • icon@3x.png
    • icon@4x.png [ 1156]

    А затем поместите их в папку Resources / Google в моем проекте ( FormsFirebase.Ui ). Так, например, EmbeddedResourceId для первого файла в приведенном выше списке - FormsFirebase.Ui.Resources.Google.icon@¾x.png.

    Как вы вскоре увидите, переименование этих файлов, как показано выше, позволит Forms9Patch.Button выбрать правильное изображение для правильного разрешения экрана (так, чтобы оно выглядело великолепно) - избавляя вас от необходимости управлять этим. Аналогично, включение их в проект .NetStandard означает, что они доступны для всех платформ - освобождая вас от необходимости разбираться с этим несколько раз!

  2. В вашем Forms9Patch.Button см. выше значок изображения в разрешении независимой моды. Это можно сделать несколькими способами. Один из более подробных способов:

    var myButton = new Forms9Patch.Button
    {
        Text = "Sign in with xxhdpi",
        TextColor=Color.White,
        FontSize=14,
        FontFamily="sans-serif",
        WidthRequest=60,
        IconImage = new Forms9Patch.Image
        {
            Source = Forms9Patch.ImageSource.FromMultiResource("FormsFirebase.Ui.Resources.Google.icon", GetType().Assembly),
            Padding = 1,
        },
        Spacing = 4,
        TintIcon = false,
        BackgroundColor = Color.FromRGB(81,134,236)
    };

Несколько замечаний:

  1. Во-первых, я установил TintIcon в false, чтобы не подкрасил значок в тот же цвет, что и TextColor. Также я установил IconImage, а не BackgroundImage. Это необходимо для того, чтобы убедиться, что изображение равноценно тексту, а не слою под ним.

  2. Также обратите внимание, что я могу установить отступы IconImage, а также Forms9Patch.Button.Padding и Forms9Patch.Button.Spacing (расстояние между IconImage и [ 1113] или HtmlText, в зависимости от того, было ли для HasTightSpacing установлено значение true).

  3. Вместо использования нескольких файлов .png (для каждого разрешения экрана), если у вас есть .svg версия вашего изображения, вы можете использовать ее вместо этого. Гораздо меньше работы!

  4. Еще одна вещь, которая может вас заинтересовать: подобно тому, как Forms9Patch обрабатывает изображения независимо от платформы (помещая их в кроссплатформенный проект в качестве встроенных ресурсов), он может сделать то же самое со шрифтами. Это означает, что вы можете поместить файл шрифта (.ttf или .otf) в ваш кроссплатформенный проект и использовать его EmbeddedResourceId в качестве значения для FontFamily. И это поведение может быть расширено до элементов Xamarin.Forms с помощью Forms9Patch.EmbeddedResourceFontEffect.

Теперь немного прозелитизма (извините, если это не относится к вам): я вижу, что вы использовали XAML в качестве примера кода. Обратите внимание, что я не в своем ответе. Если вы новичок в .Net и / или Xamarin.Forms, я настоятельно рекомендую не использовать XAML. Не поймите меня неправильно, XAML великолепен - он просто не для начинающих. Зачем? Слишком много вещей происходит под одеялом, которые, как новичок, могут сбить вас с толку и замедлить. Скорее, я бы порекомендовал вам написать весь ваш пользовательский интерфейс на C #, чтобы вы могли научиться управлять своими свойствами и узнать, как на самом деле работает привязка. Как только вы освоите создание очень эффективных макетов с наилучшим «контекстно-зависимым» использованием связывания, тогда вы готовы к XAML. Для меня настоящим тестом была возможность сделать очень сложную разметку ячейки в большом списке в ListView плавно прокручивать на недорогом телефоне Android. После этого опыта я смог воспользоваться всеми преимуществами разработки на XAML (и их немало), не беспокоясь о том, что меня сковывают мои ошибки новичка.

5
задан Michael Kelley 28 April 2009 в 23:13
поделиться

2 ответа

I agree that using TreeViewAction.Unknown in this case is less than desirable. Consider using the BeforeSelect event, which provides an opportunity to prevent the AfterSelect event.

Create a GotFocus event handler that sets a flag. Then, create a BeforeSelect event handler that, if the flag is set, cancels the event and clears the flag. For example:

private bool treeViewWasNewlyFocused = false;

private void TreeView1_BeforeSelect(object sender, TreeViewCancelEventArgs e)
{
    if(treeViewWasNewlyFocused)
    {
        e.Cancel = true;
        treeViewWasNewlyFocused = false;
    }
}

private void TreeView1_GotFocus(object sender, EventArgs e)
{
    treeViewWasNewlyFocused = true;
}
6
ответ дан 18 December 2019 в 13:19
поделиться

Мне пришлось решить ту же самую проблему (но на компактной платформе), когда событие BeforeSelect не отображается (я был сбит с толку).

Но думаю, получил довольно элегантное решение и надеюсь, что это поможет другим !!

Я создал производный элемент управления TreeView (чтобы можно было выбрать несколько элементов одновременно), но также исправлю «автоматический» выбор первого узла при получении FOCUS.

  • открытый класс TreeView_MultSel: System.Windows.Forms.TreeView

Затем я переопределил обработчики событий как таковые:

/// <summary>
/// //This actually occurs AFTER actual Treeview control:
///   -  Got Focus in reality
///   -  Executed the "innate" behaviour (like a button showing "depressed")
///   -  The "innate and UNWANTED behaviour of the Treeview is to selected the first Node 
///          when gets the focus.
///The key here is the Treeview executes in this order (when Tree Selected and didn't have focus):
///   -  First the Node is selected (before OnGotFocus is executed)
///         Since when LostFocus "treeHasFocus" = false the OnAfterSelect handler isn't called!!
///
///   -  Then the OnGotFocus is called:
///         This will set treeHasFocus to True and will not react to selections
/// </summary>
/// <param name="e"></param>
protected override void OnGotFocus(EventArgs e)
{
    treeHasFocus = true;
    //base.OnGotFocus(e);
}

/// <summary>
/// Alot easier to handle here (in Derived TreeView control then using all kinds of 
///     -= events to try to prevent.
/// 
/// This was the cleanest way I could find (prevent firing of AfterSelect)
/// </summary>
/// <param name="e"></param>
protected override void OnLostFocus(EventArgs e)                
{                                                               
    treeHasFocus = false;                                       
    //base.OnLostFocus(e);
}

/// <summary>
/// -  Treeview Control defaults to selecting the first node (when gets focus)
/// -  We do NOT want this - since would automatically Highlight the first node (select)
/// -  treeHasFocus is NOT true for the first unwanted "automatic" selection of the first item
/// -  Upon loosing Focus, the AfterSelect handler is never called.
/// </summary>
/// <param name="e"></param>
protected override void OnAfterSelect(TreeViewEventArgs e)      
{                                                               
    if (treeHasFocus)                                           
        base.OnAfterSelect(e);                                   
    this.SelectedNode = null;                                   
}
2
ответ дан 18 December 2019 в 13:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: