【问题标题】:Setting a binding for a second window为第二个窗口设置绑定
【发布时间】:2020-03-02 13:47:26
【问题描述】:

我有两个 WPF 窗口,我想将上下文设置为 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>

浏览视图模型

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();
        }
    }
}

基础视图模型

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;
    }
}

【问题讨论】:

  • 是这里没有显示错误信息的问题吗?你能在你的问题中澄清一下吗?我怀疑是这样,在这种情况下,在 errorMessage 属性的设置器中没有调用 NotifyPropertyChanged 或类似的方法,我怀疑你的 ViewModelBase 中有一个方法,它将设置一个属性并自动调用一个实现它的方法。跨度>
  • 是的,这与问题很接近,但似乎断点 eaven 有可能被击中

标签: c# mvvm datacontext


【解决方案1】:

您的 XAML 看起来正确,我高度怀疑是 ViewModel 导致它无法工作。这样的事情应该可以工作。

请注意,这在很大程度上取决于 BaseViewModel 的实现方式。如果可能的话,你可以分享这个,以便我可以更新我的答案是正确的吗?以下是您应该如何在 ViewModel 中实现属性,即 View 的 DataContext。

#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 中,您可以添加一个通用的 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>

【讨论】:

  • 感谢您分享您的 ViewModel 基础,我看不到任何引发此事件的内容。我将用一个简单的例子来更新我的 anwser。
  • 你答案的顶部我应该在哪里添加它我进入视图模型但就像我添加一个属性一样?
  • 是的,很抱歉上面的部分是 ViewModel 中的属性。无论哪个 ViewModel 是 View 的 DataContext,它都会进入。
  • 在标签上的 XAML 中尝试 Content="{Binding errorMessage, UpdateSourceTrigger=PropertyChanged}"
  • 不工作它不更新但我仍然认为该命令在某种程度上是错误的不是吗?
猜你喜欢
  • 2011-09-10
  • 2012-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-27
  • 2019-06-01
相关资源
最近更新 更多