Как изменить фоновое изображение C # wpf при открытии нового окна? - PullRequest
0 голосов
/ 22 ноября 2018

Мое главное окно имеет 4 переключателя.Пользователь должен выбрать один, а затем нажать на кнопку, которая открывает новое окно.В зависимости от выбранного переключателя, я хочу изменить фон, который появляется в новом окне.Это мой код:

public partial class Practice : Window
{
    public Practice()
    {
        InitializeComponent();

        if (((MainWindow)Application.Current.MainWindow).BinomialRadio.IsChecked == true)
        {

        }
        else if (((MainWindow)Application.Current.MainWindow).HypergeometricRadio.IsChecked == true)
        {

        }
        else if (((MainWindow)Application.Current.MainWindow).PoissonRadio.IsChecked == true)
        {
            Background = new ImageBrush(new BitmapImage(new Uri(BaseUriHelper.GetBaseUri(this), "images/poisson_practice_screen.jpg")));
        }
        else
        {

        }
    }
}

В новом окне уже есть фон по умолчанию, который я установил в свойствах кода XAML.Этот код выше работает и работает хорошо, но картина не меняется.Я нашел быстрое решение, которое в основном состоит в том, чтобы удалить фон (чтобы новое окно всегда имело пустой фон), а затем устанавливать его при каждом открытии.Есть ли лучший способ сделать это?

Спасибо всем за помощь

1 Ответ

0 голосов
/ 22 ноября 2018

Причина, по которой фон окна Practice не обновляется, заключается в том, что вы устанавливаете его фон в конструкторе окна, который запускается только при создании окна.Для его обновления необходимо добавить обработчики событий в каждый из флажков для события Checked и обновить фон в обработчике.

Однако самый простой и рекомендуемый способ сделать этоиспользуя привязку данных.Привязка данных - это конструкция в WPF и других средах, где вы декларативно указываете, какие свойства связаны друг с другом, поэтому вам не нужно обновлять их вручную.Нет написания утомительных обработчиков событий или отслеживания сложных изменений.

Practice.xaml.cs :

public partial class Practice : Window
{
    // INotifyPropertyChanged implementation is important!
    // Without it, WPF has no way of knowing that you changed your property...
    public class PracticeModel : INotifyPropertyChanged
    {
        private BitmapImage _background;

        public BitmapImage Background 
        { 
            get => _background;
            set { _background = value; PropertyChanged?.Invoke(nameof(Background)); }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

    public Practice()
    {
        InitializeComponent();

        // DataContext specifies which object the bindings are bound to
        this.DataContext = new PracticeModel();
    }
}

Practice.xaml:

<Window x:Class="MyApp.Practice" Background="{Binding Background}">
    <!-- your content here; all other attributes of Window omitted for brevity -->
</Window>

MainWindow.xaml.cs:

public partial class MainWindow : Window
{
    public Practice.PracticeModel PracticeModel { get; set; } = new Practice.PracticeModel();

    // ...

    public OnButtonClicked(RoutedEventArgs e) 
    {
        var window = new Practice();
        // DataContext specifies which object the bindings are bound to
        window.DataContext = this.PracticeModel;
        window.Show();
    }

    public OnPoissonRadioChecked(RoutedEventArgs e) 
    {
        PracticeModel.Background = new BitmapImage(new Uri(BaseUriHelper.GetBaseUri(this), "images/poisson_practice_screen.jpg"));
    }

    // likewise for other radio buttons ...
}

MainWindow.xaml:

<Window x:Class="MyApp.MainWindow">
    <RadioButton Group="TheButtons" x:Name="BinomialRadio" IsChecked="True" Checked="OnBinomialRadioChecked" />
    <RadioButton Group="TheButtons" x:Name="HypergeometricRadio" Checked="OnHypergeometricRadioChecked" />
    <RadioButton Group="TheButtons" x:Name="PoissonRadio" Checked="OnPoissonRadioChecked" />
    <RadioButton Group="TheButtons" x:Name="TheOtherRadio" Checked="OnTheOtherRadioChecked" />
</Window>

КогдаВы изменили свойство на PracticeModel, событие PropertyChanged сработало.Это сообщает WPF, что свойство изменилось, и автоматически обновляет все соответствующие привязки.Это быстро станет очень полезным, если вы хотите иметь более одного динамически обновляемого свойства.Кроме того, привязка данных может автоматически преобразовывать string или Uri в ImageSource, поэтому вам даже не нужно создавать BitmapImage самостоятельно (а если вам не нужно, то не.)

Как вы могли заметить, в этом коде все еще есть обработчики событий.Это потому, что я не хотел вносить слишком много сложности в одно и то же время, и переключатели привязки данных должным образом могут сбивать с толку тех, кто к этому не привык.Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...