从子窗口更新父窗口的数据,C# WPF

2w3kk1z5  于 2023-02-13  发布在  C#
关注(0)|答案(1)|浏览(242)

有一个父窗口,在其中声明了一个页面,页面上有一个(Edit)按钮,点击该按钮会打开一个窗口,关闭后父窗口中的数据会被更新。

视图模型父窗口

public class MasterWinViewModel : Notify
{
    private object _curentPage;

    public object CurentPage
    {
        get { return _curentPage; }
        set
        {
            _curentPage = value;
            SignalChanged("CurentPage");
        }
    }

    public UserApi ProfileUser
    { 
        get => profileUser;
        set 
        {
            profileUser = value;
            SignalChanged("ProfileUser");
        } 
    }
    public CustomCommand Main { get; set; }
    public CustomCommand Help { get; set; }
    public CustomCommand Search { get; set; }
    public CustomCommand MyMediaLibrary { get; set; }
    public CustomCommand Profile { get; set; }
    public CustomCommand Test { get; set; }

    private UserApi profileUser;

    public MasterWinViewModel()
    {

        Task.Run(GetUserId);

       

        Test = new CustomCommand(() =>
        {
            Test nn = new Test();
            nn.Show();
        });

        Main = new CustomCommand(() =>
        {
            CurentPage = new MainPage();
            SignalChanged("CurentPage");
        });

        Help = new CustomCommand(() =>
        {
            CurentPage = new HelpPage();
            SignalChanged("CurentPage");
        });

        Search = new CustomCommand(() =>
        {
            CurentPage = new SearchPage();
            SignalChanged("CurentPage");
        });

        MyMediaLibrary = new CustomCommand(() =>
        {
            CurentPage = new MyMediaLibraryPage();
            SignalChanged("CurentPage");
        });

        Profile = new CustomCommand(() =>
        {
            CurentPage = new ProfilePage();
            SignalChanged("CurentPage");
        });
    }

    public async Task GetUserId()
    {
        Task.Delay(200).Wait();
        var t = SingInWindowViewModel.UsId;
        var result = await Api.GetAsync<UserApi>(t, "User");
        ProfileUser = result;
        SignalChanged("ProfileUser");
    }
   
    

}

视图模型页面

public class ProfilePageViewModel : Notify
{
    private CustomCommand selectedAlbum;
    private List<AlbumApi> albums;

    public CustomCommand SelectedAlbum
    {
        get => selectedAlbum;
        set
        {
            selectedAlbum = value;
            SignalChanged();
        }
    }

    public List<AlbumApi> Albums 
    {
        get => albums;
        set 
        {
            albums = value;
            SignalChanged("Albums");
        } 
    }

    public CustomCommand NewAlbum { get; set; }
    public UserApi ProfileUser { get; set; }
    public CustomCommand Edit { get; set; }
    public CustomCommand EditAlbum { get; set; }
    public CustomCommand DeleteAlbum { get; set; }
    public CustomCommand Refresh { get; set; }

    public ProfilePageViewModel()
    {
        Task.Run(GetUserId);
        Task.Run(GetAlbumsList);

        Refresh = new CustomCommand(() =>
        {
            Task.Run(GetUserId);
            Task.Run(GetAlbumsList);
        });

        Edit = new CustomCommand(() =>
        {
            EditUserWindow euw = new EditUserWindow();
            euw.ShowDialog();
            Thread.Sleep(1000);
            Task.Run(GetUserId);
            
        });

        NewAlbum = new CustomCommand(() =>
        {
            AddAlbumWindow albumWindow = new AddAlbumWindow();
            albumWindow.Show();
        });
    }

    public async Task GetUserId()
    {
        var t = SingInWindowViewModel.UsId;
        var result = await Api.GetAsync<UserApi>(t, "User");
        ProfileUser = result;
        SignalChanged("ProfileUser");
    }

    public async Task GetAlbumsList()
    {
        var result = await Api.GetListAsync<AlbumApi[]>("Album");
        Albums = new List<AlbumApi>(result);
        SignalChanged("Albums");
    }

    public void Load()
    {
        Task.Run(GetUserId);
        Task.Run(GetAlbumsList);
    }
}

视图模型编辑窗口

public class EditUserWindowViewModel : Notify
{
    private BitmapImage image;
    public BitmapImage Image 
    { 
        get => image;
        set 
        {
            image = value;
            SignalChanged("Image");
        } 
    }

    public UserApi EditUser { get; set; }
    public CustomCommand SelectImage { get; set; }
    public CustomCommand SaveUser { get; set; }

    public EditUserWindowViewModel()
    {
        Task.Run(GetUserId);

        SaveUser = new CustomCommand(() =>
        {
            Task.Run(EditUsers);
            foreach (Window window in Application.Current.Windows)
            {
                if (window.DataContext == this)
                {
                    
                    CloseWin(window);
                }
            }
            
        });

        string directory = Environment.CurrentDirectory;
        SelectImage = new CustomCommand(() =>
        {
            OpenFileDialog ofd = new OpenFileDialog();
            if (ofd.ShowDialog() == true)
            {
                try
                {
                    var info = new FileInfo(ofd.FileName);
                    Image = GetImageFromPath(ofd.FileName);
                    EditUser.Image = $"/Resource/{info.Name}";
                    var newPath = directory.Substring(0, directory.Length) + EditUser.Image;
                    if (!File.Exists(newPath))
                        File.Copy(ofd.FileName, newPath, true);
                }
                catch (Exception)
                {
                    MessageBox.Show("Code error: Image Error", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        });
    }

    public void CloseWin(object obj)
    {
        Window win = obj as Window;
        win.Close();
    }

    private BitmapImage GetImageFromPath(string url)
    {
        BitmapImage img = new BitmapImage();
        img.BeginInit();
        img.CacheOption = BitmapCacheOption.OnLoad;
        img.UriSource = new Uri(url, UriKind.Absolute);
        img.EndInit();
        return img;
    }

    public async Task EditUsers()
    {
        await Api.PutAsync<UserApi>(EditUser, "User");
    }

    public async Task GetUserId()
    {
        var t = SingInWindowViewModel.UsId;
        var result = await Api.GetAsync<UserApi>(t, "User");
        EditUser = result;
        SignalChanged("EditUser");
    }

    
    
}

我试图在关闭子窗口后更新数据,但这并没有解决问题。因为子窗口不知道父窗口。

pbpqsu0x

pbpqsu0x1#

我建议您在每个页面对象上使用事件。
下面的代码是它的最小示例。

    • 视图模型父窗口**
public class MasterWinViewModel : Notify
{
    private object _curentPage;

    public object CurentPage
    {
        get { return _curentPage; }
        set
        {
            _curentPage = value;
            SignalChanged("CurentPage");
        }
    }
    
    public CustomCommand Profile { get; set; }       

    public MasterWinViewModel()
    {        
        Profile = new CustomCommand(() =>
        {
            ProfilePage profilepage = new ProfilePage();

            profilepage.OnEventFire += (sender, data) => 
            {
                //sender = profilepage
                //data = data object from profilepage
                //Do something with sent data.              
            }               

            CurentPage = profilepage;

            SignalChanged("CurentPage");
        });
    }      
}
    • 配置文件页面视图模型**
public class ProfilePageViewModel : Notify
{    
    public delegate void EventDelegate(object sender, object data);
    
    public event EventDelegate OnEventFire = null;
    
    public ProfilePageViewModel()
    {
        
    } 
    
    public void EventFireMethod(object data) 
    {
        //Fire Event
        OnEventFire?.Invoke(this, data);
    }   
}

在ProfilePage类中调用EventFireMethod后,将调用回调方法。
这样就可以在父窗口和子页面对象之间发送数据。

相关问题