Задать вопрос
  • Как задать имя для порта программы в UFW?

    @ayaout
    ayavrik
    Создать файл с названием приложения, службы и т.д.
    /etc/ufw/applications.d/name-applications

    Добавить в файл
    [name-applications]
    title=A title
    description=A description
    #список правил для "name-applications"
    ports=xxx/tcp|xxx/udp|xxxx:xxxx/udp

    обновить app list
    sudo ufw app update name-applications
    включить правило
    sudo ufw allow name-applications

    Можно просто добавить комментарий ( comment 'name-applications' ) в конце правила.
    sudo ufw allow in on eth0 to any port 80 comment 'name-applications'
    Ответ написан
    Комментировать
  • Как задать имя для порта программы в UFW?

    @unseriously
    Задать имя для порта?? Нельзя так. Но, есть волшебный файлик /etc/services , который показывает кто на каком порту сидит.
    Ответ написан
    Комментировать
  • Как отобразить только определенные элементы из массива в цикле v-for во Vue JS?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Я так понимаю надо какой-то фильтр применить для отображения?

    Можно и фильтр:

    filters: {
      numberOnly: val => /^\d+$/.test(val) ? val : '',
    },

    <div v-for="n in squares">
      {{ n | numberOnly }}
    </div>

    Но не обязательно:

    <div v-for="n in squares">
      {{ Number.isNaN(+n) ? '' : n }}
    </div>

    Если знаете, в каких местах находятся нужные элементы, то

    <div v-for="(n, i) in squares">
      {{ i % 11 ? '' : n }}
    </div>

    Или, если знаете сами элементы:

    data: () => ({
      itemsToShow: [...Array(10)].map((n, i) => `${i + 1}`),
      ...
    }),

    <div v-for="n in squares">
      {{ itemsToShow.includes(n) ? n : '' }}
    </div>
    Ответ написан
    1 комментарий
  • Как изменить css в библиотеке, которую использует моё приложеине на netlify?

    Kozack
    @Kozack Куратор тега CSS
    Thinking about a11y
    • Форкнуть библиотеку, изменить и использовать в проекте
    • Переопределять свойства библиотеки — собственными
    • Написать автору библиотеки об возможности кастомизизации
    Ответ написан
    Комментировать
  • Как изменить css в библиотеке, которую использует моё приложеине на netlify?

    Aetae
    @Aetae Куратор тега Vue.js
    Тлен
    Стили же вручную подключаются, из описания:
    import 'vue-toast-notification/dist/theme-default.css';
    //import 'vue-toast-notification/dist/theme-sugar.css';

    Просто скопируй css в проект, изменяй и подключай напрямую: import './theme-default.css'; или типа того.
    Ну элементарная логика же.

    А изменения в node_modules в любом случае только локальны, в этом вся суть - не таскать код библиотек с кодом проекта. Если очень надо - можно сделать копию библиотеки и подключить через file:\link:, но это не ваш случай.
    Ответ написан
    Комментировать
  • Как показать уведомление с анимацией без перезагрузки встраницы после сохранения формы в Spring Boot?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Здравствуйте!
    Вы все правильно предположили насчет Ajax & JS + CSS.
    Писать код с нуля не буду, а лишь расскажу вам этапы для достижения желаемого...
    1) Создайте метод, который на ajax запрос будет возвращать @ResponseBody, либо создайте контроллер и добавьте аннотацию @RestController
    2) Перед закрывающим тегом </body> добавьте js код для аякс.
    https://ruseller.com/jquery.php?id=11
    https://api.jquery.com/jquery.ajax/
    3) Далее в контроллере обрабатываете запрос и возвращаете String или например, Map<String, String> с нужными данными.
    4) В ajax на событие success показываете ваш блок с анимацией.

    Теперь, про саму анимацию...
    Анимацию можно сделать средствами CSS или JS.
    Вот, пример CSS
    Допустим вот, ваш блок и он по умолчанию скрыт
    <div class="notify" style="display:none;"></div>
    При success делаете этот блок show() (видимым).
    Показать - https://api.jquery.com/show/
    Скрыть - https://api.jquery.com/hide/

    Остается только добавить анимацию - @keyframes
    https://www.w3schools.com/css/css3_animations.asp

    Вот, готовые библиотеки -
    https://stephanwagner.me/jBox
    https://notifyjs.jpillora.com/
    Ответ написан
    1 комментарий
  • Как сделать логин для админа в Spring Security?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Здравствуйте!
    Я реализовал это следующим образом:
    В данном случае у меня 2 кастомные формы входа:
    1) для админ панели /admin/login
    2) для пользователей /auth
    /**
     * Конфигурация для Spring Security
     */
    @Configuration
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class WebSecurityConfig {
    
        private static UserDetailsServiceImpl userDetailsService;
    
        @Autowired
        private UserDetailsServiceImpl userDetailsServiceImpl;
    
        @PostConstruct
        private void init() {
            userDetailsService = this.userDetailsServiceImpl;
        }
    
        @Bean
        public static PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    
        @Bean
        public DaoAuthenticationProvider authProvider() {
            CustomAuthenticationProvider authProvider = new CustomAuthenticationProvider();
            authProvider.setUserDetailsService(userDetailsService);
            authProvider.setPasswordEncoder(passwordEncoder());
            return authProvider;
        }
    
        // Конфигурация для backend
        @Configuration
        @Order(1)
        public static class BackendConfigurationAdapter extends WebSecurityConfigurerAdapter {
    
    
            @Autowired
            private CustomWebAuthenticationDetailsSource authenticationDetailsSource;
    
            public BackendConfigurationAdapter() {
                super();
            }
    
            @Override
            protected void configure(HttpSecurity http) throws Exception {
    
                http
                        .antMatcher("/admin/**")
                        .antMatcher("/admin/**/**")
                        .authorizeRequests()
                        .anyRequest()
                        .hasAuthority("ADMIN_PRIVILEGE")
                        /*.hasAuthority("ADMIN")*/
    
    
                        .and()
                            .formLogin()
                            .authenticationDetailsSource(authenticationDetailsSource)
                            .loginPage("/admin/login")
                            .loginProcessingUrl("/admin/login")
                            .usernameParameter("email")
                            .passwordParameter("password")
                            .defaultSuccessUrl("/admin/dashboard")
                            .failureUrl("/admin/login?authError")
                            .permitAll()
    
                        .and()
                            .rememberMe()
                            .rememberMeParameter("remember-me")
                            .tokenValiditySeconds(86400)
    
                        .and()
                            .logout()
                            .logoutRequestMatcher(new AntPathRequestMatcher("/admin/logout"))
                            .logoutSuccessUrl("/admin/login")
                            .deleteCookies("JSESSIONID")
    
                        .and()
                            .exceptionHandling()
                            .accessDeniedPage("/403")
    
                        .and()
                            .csrf()
                            .ignoringAntMatchers("/admin/**");
            }
    
            @Override
            public void configure(WebSecurity web) {
                web.ignoring().antMatchers(
    
                        // статика backend
                        "/backend/css/**",
                        "/backend/js/**",
                        "/backend/fonts/**",
                        "/backend/images/**",
                        "/backend/init/**"
    
                );
            }
    
    
            @Override
            protected void configure(AuthenticationManagerBuilder auth) throws Exception {
                auth.userDetailsService(userDetailsService);
            }
    
        }
    
    
        // Конфигурация для frontend (Обычная авторизация и авторизация oauth2)
        @Configuration
        @Order(2)
        public static class FrontendConfigurationAdapter extends WebSecurityConfigurerAdapter {
    
            @Autowired
            private CustomWebAuthenticationDetailsSource authenticationDetailsSource;
    
            public FrontendConfigurationAdapter() {
                super();
            }
    
            protected void configure(HttpSecurity http) throws Exception {
    
                http
                        .authorizeRequests().mvcMatchers("/robots.txt").permitAll()
                        .antMatchers(
                                "/", "/auth", "/signup", "/restore", "/activation/**",
                                "/admin/login", "/admin_restore",
                                "/attachments/get/**",
                                "/sendMessage",
                                "/error",
                                "/page/**",
                                "/categories", "/categories/**",
                                "/terms/**", "/posts", "/posts/**"
                        ).permitAll()
                        .anyRequest().authenticated()
    
                        .and()
                            .formLogin()
                            .authenticationDetailsSource(authenticationDetailsSource)
                            .loginPage("/auth")
                            .loginProcessingUrl("/auth")
                            .usernameParameter("email")
                            .passwordParameter("password")
                            .defaultSuccessUrl("/")
                            .failureUrl("/auth?authError")
                            .permitAll()
    
                        .and()
                            .rememberMe()
                            .rememberMeParameter("remember-me")
                            .tokenValiditySeconds(86400)
    
                        .and()
                            .oauth2Login().defaultSuccessUrl("/")
    
                        .and()
                            .logout()
                            .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                            .logoutSuccessUrl("/")
                            .deleteCookies("JSESSIONID")
    
                        .and()
                            .exceptionHandling()
                            .accessDeniedPage("/403")
    
                        .and()
                            .csrf()
    
                        .and()
                            .sessionManagement()
                            .sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
    
                        .and()
                            .headers().frameOptions().sameOrigin();
                        
    
            }
    
            @Override
            public void configure(WebSecurity web) {
                web.ignoring().antMatchers(
                        "/frontend/css/**",
                        "/frontend/js/**",
                        "/frontend/fonts/**",
                        "/frontend/images/**",
                        "/frontend/lib/**",
                        "/frontend/vendor/**"
                );
            }
    
            @Override
            protected void configure(AuthenticationManagerBuilder auth) throws Exception {
                auth.userDetailsService(userDetailsService);
            }
    
    
        }
    
    }


    Админа, как по мне, лучше создать при инициализации приложения. Вот, код, как это делаю я.

    @Component
    public class InitData implements CommandLineRunner {
    
    @Override
    public void run(String... args) throws Exception {
    if (userServiceImpl.usersCount() == 0)
                initUsers();
    }
    
    private void initUsers() {
    // создаем пользователей
    }
    }
    Ответ написан
    3 комментария
  • Как создать кастомные страницы для Access Denied Page и Error Whitelabel Page в Spring Security?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Здравствуйте!
    Access denied (Forbidden) - 403 ошибка.
    Создайте controller или controllerAdvice для http ошибок.

    @Controller
    public class HttpErrorController implements ErrorController {
    
        private final MessageSource messageSource;
    
        @Autowired
        public HttpErrorController(MessageSource messageSource) {
            this.messageSource = messageSource;
        }
    
        @RequestMapping("/error")
        public String handleError(
                Locale locale,
                Model model,
                HttpServletRequest request,
                Exception ex
        ) {
    
            Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
    
            if (status != null) {
    
                int statusCode = Integer.valueOf(status.toString());
    
                Map<String, String> metaData = new HashMap<>();
    
                // 403
                if (statusCode == HttpStatus.FORBIDDEN.value()) {
    
                   // do somthing
                }
    
                // 404
                else if (statusCode == HttpStatus.NOT_FOUND.value()) {
                    // do somthing
                }
    
                // 405
                else if (statusCode == HttpStatus.NOT_FOUND.value()) {
                    // do somthing
                }
    
                // 500
                else if (statusCode == HttpStatus.INTERNAL_SERVER_ERROR.value()) {
                   // do somthing
                }
    
            }
    
    
            return "templates/errors/httperrors";
        }
    
        @Override
        public String getErrorPath() {
            return "/error";
        }
    
    }


    Чтобы отключить whitelibel page добавьте в properties
    # Disable Whitelabel Error Page
    server.error.whitelabel.enabled=false
    Ответ написан
    1 комментарий
  • Как автоматически вывести все блоки в thymeleaf?

    @Kot1que
    пишу на жаве
    Вообще по-хорошему добавить еще слой сервисов, но для простоты примера не стал.

    public interface VideoRepository extends CrudRepository<Video, Integer> {
    }


    @Controller
    public class HomeController {
        @Autowired
        private final VideoRepository videoRepository;
    
        @GetMapping("/tutorials")
            public String tutorials(Model model) {
                model.add("videos", videoRepository.findAll());
                return "tutorials";
            }
    }


    <div class="video-container">
            <div class="video-item" th:each="video: ${videos}">
                <iframe th:src="${video.url}"
                        frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
                        allowfullscreen></iframe>
                <h3 th:text="${video.title}"></h3>
            </div>
    </div>
    Ответ написан
    1 комментарий
  • Почему не отображаются изображения из static resources?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Стоп!

    Итак, не отображается картинка. В консоли ошибка 404.

    Решение - Build Project (ctrl + F9) или Rebuild Project и Спринг увидит вашу новую статику и все будет работать.

    + если используете Spring Security, то:

    @Override
            public void configure(WebSecurity web) {
                web.ignoring().antMatchers(
    
                        // статика
                        "/css/**",
                        "/js/**",
                        "/fonts/**",
                        "/images/**"
                );
            }
    Ответ написан
    2 комментария
  • Как подставить класс в Thymeleaf?

    azerphoenix
    @azerphoenix Куратор тега Spring
    Java Software Engineer
    Здравствуйте!
    Вы можете сделать это на уровне thymeleaf

    Что-то типа такого должно сработать:

    <li><a href="#" class="link-item" th:classapend="${#strings.contains(#httpServletRequest.requestURI, '/tutorials')} ? colorClass : baseClass">Tutorials</a></li>


    Тут мы из запроса получаем URL, проверяем содержится ли в URL /tutorials и если да, то добавляем класс colorClass, а если нет, то baseClass.

    Изучите th:class & th:classappend
    Ответ написан
    3 комментария
  • Почему сборка gradle проекта длится очень долго?

    zolt85
    @zolt85
    Программист
    В случае bootRun в консоли IDEA (да и в любой другой консоли) так и будет крутиться bootRun на 80% (условно). Вы же запускаете приложение этой командой, вот оно и запускается, и работает, до тех пор пока Вы сами его не остановите, либо пока в программе не произойдет критической ошибки, при которой произойдет завершение программы. Как правило для сборки (именно сборки) приложения SpringBoot используют таски bootJar/bootWar. Уверяю Вас, они конечны, и работают достаточно шустро.
    Ответ написан
    2 комментария
  • Как оптимизировать анимации?

    @AlexHell
    я в WPF не шарю, мимо проходил
    есть опыт в Win Forms, Unity и сопутствующем
    может быть помогу чемто

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

    Врятли, т.к. у объекта-анимации есть продолжительность, и он самоуничтожается под капотом по истечении таймера, вручную нет смысла удалять, я бы спроектировал именно так внутри (под капотом WPF всмысле)
    Судя по примерам (я не эксперт WPF) делать надо именно так, как у вас и сделано.

    вполне может быть что траблы с перформансом по таким причинам
    * ShowCard вызывается слишком часто, а этого кода вы не привели, вполне могут быть проблемы, например цикл из ShowCard или вызов его каждый такт (update или что там у вас в WPF)
    без защитного флага
    тогда когда надо сделать чтото в духе
    if (! isAnimPlayed)
    {
      isAnimPlayed = true;
      ShowCard ();
    }

    * слабый другой ПК, CPU \ GPU, уточняйте и тестите на аналогичных
    * много что модифицируется, т.е. window.cardQuestionBorder.RenderTransform это чтото большое и у него есть какието лишние потомки, и можно както разбить по-лучше
    Ответ написан
    6 комментариев
  • Как убрать черную обводку при наведении мыши на кнопку?

    @yuopi
    C# developer
    Надо либо Border'у выставить свойство
    RenderOptions.EdgeMode="Aliased"
    , но тогда графика совсем не о чем

    Либо рисовать второй бордер:
    Код

    <Style x:Key="RoundedButton" TargetType="Button">
                <Setter Property="Grid.Column" Value="1"/>
                <Setter Property="Margin" Value="20 32"/>
                <Setter Property="HorizontalContentAlignment" Value="Center" />
                <Setter Property="VerticalContentAlignment" Value="Center" />
                <Setter Property="FontSize" Value="14"/>
                <Setter Property="FontFamily" Value="Verdana"/>
                <Setter Property="Foreground" Value="White"/>
                <Setter Property="Background" Value="Transparent"/>
    
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type Button}">
                            <Grid>
                                <Border Name="RoundedButtonBorder"
                                Margin="0"
                                CornerRadius="15"
                                Background="{TemplateBinding Background}"
                                BorderBrush="White"
                                BorderThickness="3"
                                >
                                    <ContentPresenter HorizontalAlignment="Center"
                                              VerticalAlignment="Center"
                                             >
                                    </ContentPresenter>
                                </Border>
                                <Border Name="RoundedButtonBorderHidden"
                                Margin="0"
                                CornerRadius="15"
                                BorderBrush="White"
                                BorderThickness="5"
                                        Visibility="Hidden"
                                >
                                    <ContentPresenter HorizontalAlignment="Center"
                                              VerticalAlignment="Center"
                                             >
                                    </ContentPresenter>
                                </Border>
                            </Grid>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsMouseOver" Value="true">
                                    <Setter Property="Background" Value="White" />
                                    <Setter Property="Foreground" Value="Black" />
                                    <Setter TargetName="RoundedButtonBorderHidden" Property="Visibility" Value="Visible"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
    Ответ написан
    5 комментариев
  • Как заменить конструкцию if else на switch?

    freeExec
    @freeExec
    Участник OpenStreetMap
    Но со switch не будет компактней.
    Компактней будет если ты свои CategoryToggle и RectangleCategory разместишь в массивы. И тогда у тебя логика будет только одна, проверить чекер и применить браш.
    for (int i = 0; i < categoryToggleArr.Length; i++)
    {
       if (categoryToggleArr[i].IsChecked)
       {
          RectCategoryArr[i].Fill = new SolidColorBrush(dialog.Color);
          RectangleCategoryArr[i] = new BrushConverter().ConvertToString(dialog.Color);
       }
    }
    Ответ написан
    Комментировать
  • Как перенести метод для кнопок в отдельный класс в WPF?

    @yuopi
    C# developer
    Создаете класс Animations.cs
    Пишите там эти методы
    public void OpenOptions(...) //передаем все необходимые параметры
            {  ...  }


    в MainForm создаем экземпляр класса Animation и вызываем просто нужные методы из него
    private void OpenOptions(object sender, RoutedEventArgs e)
    {  
    Animations.OpenOptions(...,...,...);
    }
    Ответ написан
    Комментировать
  • Как перенести метод для кнопок в отдельный класс в WPF?

    @Jewish_Cat
    Увлекаюсь C#
    Изучай паттер MVVM и его используй.

    Пример:
    Код взял из боевого решения. Если будет непонятно, спрашивайте
    public partial class SetColdBalance : Window
        {
    
            public SetColdBalance()
            {
                InitializeComponent();
            }
        }

    public class RelayCommand<T> : ICommand
        {
            #region Fields
    
            readonly Action<T> _execute = null;
            readonly Predicate<T> _canExecute = null;
    
            #endregion
    
            #region Constructors
    
            /// <summary>
            /// Initializes a new instance of <see cref="DelegateCommand{T}"/>.
            /// </summary>
            /// <param name="execute">Delegate to execute when Execute is called on the command.  This can be null to just hook up a CanExecute delegate.</param>
            /// <remarks><seealso cref="CanExecute"/> will always return true.</remarks>
            public RelayCommand(Action<T> execute)
                : this(execute, null)
            {
            }
    
            /// <summary>
            /// Creates a new command.
            /// </summary>
            /// <param name="execute">The execution logic.</param>
            /// <param name="canExecute">The execution status logic.</param>
            public RelayCommand(Action<T> execute, Predicate<T> canExecute)
            {
                if (execute == null)
                    throw new ArgumentNullException("execute");
    
                _execute = execute;
                _canExecute = canExecute;
            }
    
            #endregion
    
            #region ICommand Members
    
            ///<summary>
            ///Defines the method that determines whether the command can execute in its current state.
            ///</summary>
            ///<param name="parameter">Data used by the command.  If the command does not require data to be passed, this object can be set to null.</param>
            ///<returns>
            ///true if this command can be executed; otherwise, false.
            ///</returns>
            public bool CanExecute(object parameter)
            {
                return _canExecute == null ? true : _canExecute((T)parameter);
            }
    
            ///<summary>
            ///Occurs when changes occur that affect whether or not the command should execute.
            ///</summary>
            public event EventHandler CanExecuteChanged
            {
                add { CommandManager.RequerySuggested += value; }
                remove { CommandManager.RequerySuggested -= value; }
            }
    
            ///<summary>
            ///Defines the method to be called when the command is invoked.
            ///</summary>
            ///<param name="parameter">Data used by the command. If the command does not require data to be passed, this object can be set to <see langword="null" />.</param>
            public void Execute(object parameter)
            {
                _execute((T)parameter);
            }
    
            #endregion
        }

    <Window x:Class="AdminTool.SetColdBalance"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
            xmlns:local="clr-namespace:AdminTool"
            mc:Ignorable="d"
            Title="Задать баланс"
            Height="150"
            Width="250"
            ResizeMode="NoResize"
            WindowStartupLocation="CenterScreen"">
        <Window.DataContext>
            <local:ColdWalletViewModel/>
        </Window.DataContext>
        <Grid>
         <Button Grid.Row="2" Width="100" Height="30" Content="Save" Command="{Binding SaveColdWallets}"/>
        </Grid>
    </Window>

    public class ColdWalletViewModel : BindableBase
        {
            ICommand _saveColdWallet;
            public ICommand SaveColdWallets
            {
                get
                {
                    return _saveColdWallet ?? (_saveColdWallet = new RelayCommand<object[]>((obj) =>
                    {
                       ///Тут пишешь что должна выполнять твоя кнопка
                    }), /*Тут можно написать условие при котором можно будет выполнить данную команду*/);
                }
            }
        }

    /// <summary>
        ///     Implementation of <see cref="INotifyPropertyChanged" /> to simplify models.
        /// </summary>
        public abstract class BindableBase : INotifyPropertyChanged
        {
            /// <summary>
            ///     Multicast event for property change notifications.
            /// </summary>
            public event PropertyChangedEventHandler PropertyChanged;
    
            /// <summary>
            ///     Checks if a property already matches a desired value.  Sets the property and
            ///     notifies listeners only when necessary.
            /// </summary>
            /// <typeparam name="T">Type of the property.</typeparam>
            /// <param name="storage">Reference to a property with both getter and setter.</param>
            /// <param name="value">Desired value for the property.</param>
            /// <param name="propertyName">
            ///     Name of the property used to notify listeners.  This
            ///     value is optional and can be provided automatically when invoked from compilers that
            ///     support CallerMemberName.
            /// </param>
            /// <returns>
            ///     True if the value was changed, false if the existing value matched the
            ///     desired value.
            /// </returns>
            protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
            {
                if (Equals(storage, value))
                {
                    return false;
                }
    
                storage = value;
                this.OnPropertyChanged(propertyName);
                return true;
            }
    
            /// <summary>
            ///     Notifies listeners that a property value has changed.
            /// </summary>
            /// <param name="propertyName">
            ///     Name of the property used to notify listeners.  This
            ///     value is optional and can be provided automatically when invoked from compilers
            ///     that support <see cref="CallerMemberNameAttribute" />.
            /// </param>
            protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
            {
                this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    Ответ написан
    5 комментариев
  • Как деактивировать все toggle button кроме одного при клике?

    SpacePurr
    @SpacePurr
    c#, wpf
    Определите такой стиль
    <Window.Resources>
        <Style TargetType="RadioButton" BasedOn="{StaticResource {x:Type ToggleButton}}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate>
                        <ToggleButton IsChecked="{Binding IsChecked, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
                            Content="{Binding Content, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>


    Теперь просто объявите нужное количество RadioButton
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
    
        <RadioButton Grid.Column="0" Width="50" Height="50" />
        <RadioButton Grid.Column="1" Width="50" Height="50" />
        <RadioButton Grid.Column="2" Width="50" Height="50" />
    </Grid>


    При нажатии на кнопку только она становится активной. При повторном нажатии на нее она становится неактивной.

    5de755219b192060452254.gif

    Также, если вы хотите сделать группы таких кнопок, вам нужно добавить к RadioButton свойство GroupName с именем группы.
    <RadioButton GroupName="Group1"/>
    <RadioButton GroupName="Group1"/>
    <RadioButton GroupName="Group1"/>
    
    <RadioButton GroupName="Group2"/>
    <RadioButton GroupName="Group2"/>
    <RadioButton GroupName="Group2"/>


    Тогда нажатие на кнопку из Group1 никак не будет влиять на кнопки из Group2.
    Ответ написан
    5 комментариев
  • Как получить доступ к главному окну из другого класса в WPF?

    SpacePurr
    @SpacePurr
    c#, wpf
    Передача this в конструктор нового класса.

    class HotKeys
    {
         private MainWindow window;
         //Конструктор
         public HotKeys(MainWIndow _window)
         {
              window = _window;
         }
    }


    namespace Toolkits
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
           
            public MainWindow()
            {
                InitializeComponent();
                HotKeys hk = new HotKeys(this);           
            }
        }
    }
    Ответ написан
    1 комментарий