WPF Как правильно изменить вид из ICommand с MVVM - PullRequest
0 голосов
/ 21 февраля 2019

Мне нужно загрузить ComboBox ItemsSource перед расширением элемента управления.И если загрузка не удалась, я хочу установить цвет кисти границы и показать подсказку с ошибкой.Могу ли я сделать это в методе ICommand.Execute или использовать что-то вроде ValidationRule?

Код:

class ViewModel : INotifyPropertyChanged
{
    public string Server { get {...} set {...} }
    public ObservableCollection<string> ServerCollection { get; }

    public ICommand LoadServerListCommand { get; }

    protected ConnectionViewModel()
    {
        ServerCollection = new ObservableCollection<string>();
        LoadServerListCommand = new DelegateCommand( LoadServerList );
    }

    private void LoadServerList( object param )
    {
        var comboBox = param as ComboBox;
        if ( comboBox != null && !comboBox.IsDropDownOpen )
        {
            try
            {
                ServerCollection.Clear();
                ///... Load();

                comboBox.BorderBrush = //default;
                comboBox.ToolTip = null;
            }
            catch( InvalidOperationException ex )
            {
                comboBox.BorderBrush = //red;
                comboBox.ToolTip = new ToolTip()
                {
                    Content = ex.Message
                };
            }
        }
    }
}

XAML:

<ComboBox x:Name="cbServer" ItemsSource="{Binding ServerCollection}" 
          SelectedItem="{Binding Server, Mode=TwoWay}">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="PreviewMouseDown">
            <i:InvokeCommandAction Command="{Binding Path=LoadServerListCommand}" 
                                   CommandParameter="{Binding ElementName=cbServer}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</ComboBox>

1 Ответ

0 голосов
/ 21 февраля 2019

Вы можете добавить свойство в модель представления, которое указывает, была ли загрузка успешной, привязать к этому свойству и изменить соответствующие свойства ComboBox, используя Style и DataTrigger в представлении.

Установка BorderBrush для ComboBox требует от вас определения пользовательского шаблона для его ToggleButton, хотя: https://blog.magnusmontin.net/2014/04/30/changing-the-background-colour-of-a-combobox-in-wpf-on-windows-8/

Будет проще обернуть ComboBox в Borderэлемент:

<Border BorderThickness="1">
    <ComboBox x:Name="cbServer" ItemsSource="{Binding ServerCollection}"
                  SelectedItem="{Binding Server, Mode=TwoWay}">
        <ComboBox.Resources>
            <SolidColorBrush x:Key="{x:Static SystemColors.WindowFrameBrushKey}" Color="Red"/>
        </ComboBox.Resources>
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Loaded">
                <i:InvokeCommandAction Command="{Binding Path=LoadServerListCommand}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
        <ComboBox.Style>
            <Style TargetType="ComboBox">
                <Setter Property="ToolTip" Value="{Binding Error}" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Error.Length, FallbackValue=0}" Value="0">
                        <Setter Property="ToolTip" Value="{x:Null}" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ComboBox.Style>
    </ComboBox>
    <Border.Style>
        <Style TargetType="Border">
            <Setter Property="BorderBrush" Value="Red" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding Error.Length, FallbackValue=0}" Value="0">
                    <Setter Property="BorderBrush" Value="{x:Null}" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Border.Style>
</Border>

Просмотр модели:

private void LoadServerList(object parameter)
{
    try
    {
        //throw new InvalidOperationException("test");
        ServerCollection.Clear();
        ///... Load();
        Error = string.Empty;
    }
    catch (InvalidOperationException ex)
    {
        Error = ex.Message;
    }
}

private string _error;
public string Error
{
    get { return _error; }
    set { _error = value; NotifyPropertyChanged(); }
}


public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
    if (PropertyChanged != null)
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...