Установка привязки для второго окна - PullRequest
0 голосов
/ 02 марта 2020

У меня есть два WPF windows, и я хочу установить контекст для ViewModel, но если я напишу:

this.DataContext = new myViewModel() 

во второй windows cs, это не работает, вот мой код , я пытался поместить привязку в XAML и подключить контекст, но когда я пытаюсь все отладить, я получаю код ошибки, эта точка останова не будет запущена.

BrowseDialog.xaml

 <Window x:Class="TextalkApi.BrowseDialog"
        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:local="clr-namespace:TextalkApi"
        mc:Ignorable="d"
        Title="BrowseDialog" Height="248.361" Width="427.459">
    <Grid>
        <Button Content="Browse" HorizontalAlignment="Left" Margin="267,11,0,0" VerticalAlignment="Top" Width="75"/>
        <TextBox x:Name="FileDialog" HorizontalAlignment="Left" Height="23" Margin="10,10,0,0" TextWrapping="Wrap" Text="{Binding webUrl}" VerticalAlignment="Top" Width="244"/>
        <Button Content="Save" HorizontalAlignment="Left" Margin="267,166,0,0" VerticalAlignment="Top" Width="75" Command="{Binding SaveCommand}" />
        <TextBox HorizontalAlignment="Left" Height="23" Margin="10,38,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
        <Label Content="{Binding errorMessage}" HorizontalAlignment="Left" Margin="10,167,0,0" VerticalAlignment="Top" RenderTransformOrigin="-5.611,10.822" Width="207" Height="19"/> 
    </Grid>
</Window>

BrowseViewModel

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Input;
using System.Threading;
using System.Threading.Tasks;
using System.Configuration;
using System.Collections.Specialized;
using System.IO;

namespace Data
{
    public class BrowseViewModel : BaseViewModel
    {
        #region public variables
        public string webUrl { get; set; }
        public string errorMessage { get; set; }
        #endregion

        #region Public Commands
        public ICommand SaveCommand { get; set; }
        #endregion

        #region Constructor
        public BrowseViewModel()
        {
            this.SaveCommand = new RelayCommand(SaveFilePath);
        }
        #endregion

        #region Private methods
        private void SaveFilePath()
        {
            if (File.Exists(webUrl))
            {
                ConfigurationManager.AppSettings.Add("WebUrl", webUrl);
            }
            else
            {
                errorMessage = "Filen existerar ej"; 
            }
        }
        #endregion
    }
}

BrowseDialog.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.IO;
using Data;

namespace TextalkApi
{
    /// <summary>
    /// Interaction logic for BrowseDialog.xaml
    /// </summary>
    public partial class BrowseDialog : Window
    {
        public BrowseDialog()
        {
            InitializeComponent();
            this.DataContext = new BrowseViewModel();
        }
    }
}

BaseViewModel

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using PropertyChanged;

namespace Data
{
    [AddINotifyPropertyChangedInterface]

    public class BaseViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    }
}

1 Ответ

1 голос
/ 02 марта 2020

Ваш XAML выглядит правильно, и я очень подозреваю, что именно ViewModel заставляет его не работать. Нечто подобное должно работать.

Обратите внимание, что это будет во многом зависеть от того, как реализован BaseViewModel. Если возможно, вы можете поделиться этим, чтобы я мог обновить свой ответ, чтобы быть правильным? Ниже показано, как вам следует реализовать свойства в вашей ViewModel, которая является DataContext для View.

#region Properties
    private string _webUrl;
    public string WebUrl 
    { 
        get => _webUrl;     
        set 
        {
            //This will change based on how you have implemented your BaseViewModel!
            //The method name might be different, or have different parameters!
            this.SetProperty(ref _webUrl, value, nameof(WebUrl));
            //Call the save file path validation method...
            SaveFilePath();
        }
    }

    private string _errorMessage;
    public string ErrorMessage 
    { 
        get => _errorMessage;           
        private set 
        {
            //This will change based on how you have implemented your BaseViewModel!
            //This method should call NotifyPropertyChange to notify the UI to update...
            this.SetProperty(ref _errorMessage, value, nameof(ErrorMessage));
        }
    }
#endregion

В вашей ViewModelBase вы можете добавить обобщенный метод c SetProperty, который затем может обрабатывать поднятие измененного свойства событие для вас. Примерно так:

public class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public void SetProperty<T>(ref T storage, T value, string propertyName)
    {
        storage = value;
        RaisePropertyChangedEvent(propertyName);
    }

    protected void RaisePropertyChangedEvent(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

и из-за изменений в ViewModel вам также потребуется обновить привязки в вашем XAML.

<Grid>
    <Button Content="Browse" HorizontalAlignment="Left" Margin="267,11,0,0" VerticalAlignment="Top" Width="75"/>
    <TextBox x:Name="FileDialog" HorizontalAlignment="Left" Height="23" Margin="10,10,0,0" TextWrapping="Wrap" Text="{Binding WebUrl}" VerticalAlignment="Top" Width="244"/>
    <Button Content="Save" HorizontalAlignment="Left" Margin="267,166,0,0" VerticalAlignment="Top" Width="75" Command="{Binding SaveCommand}" />
    <TextBox HorizontalAlignment="Left" Height="23" Margin="10,38,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
    <Label Content="{Binding ErrorMessage}" HorizontalAlignment="Left" Margin="10,155,0,0" VerticalAlignment="Top" RenderTransformOrigin="-5.611,10.822" Width="207" Height="46"/>
</Grid>
...