Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 当一组属性之一发生更改时在代码中生成字符串_Wpf_Binding_Properties - Fatal编程技术网

Wpf 当一组属性之一发生更改时在代码中生成字符串

Wpf 当一组属性之一发生更改时在代码中生成字符串,wpf,binding,properties,Wpf,Binding,Properties,我正在寻求有关如何在多处房产发生变化时获得通知的建议 例如,假设我想将控件的文本绑定到WPF ViewModel中的FullAddress属性,只要一组属性(如StreetNumber、StreetName、郊区、邮政编码等)发生更改,我就可以动态计算该属性 我想我需要将显示控件绑定到FullAddress属性,但是如何让它在一个依赖属性更改时自动更新?我可以将属性的codebehind绑定到同一ViewModel上的多个其他属性吗?如果是,怎么做?有更好的方法吗?假设您的类实现了INotify

我正在寻求有关如何在多处房产发生变化时获得通知的建议

例如,假设我想将控件的文本绑定到WPF ViewModel中的FullAddress属性,只要一组属性(如StreetNumber、StreetName、郊区、邮政编码等)发生更改,我就可以动态计算该属性


我想我需要将显示控件绑定到FullAddress属性,但是如何让它在一个依赖属性更改时自动更新?我可以将属性的codebehind绑定到同一ViewModel上的多个其他属性吗?如果是,怎么做?有更好的方法吗?

假设您的类实现了INotifyPropertyChanged,那么您可以在任何属性设置器中进行通知。例如

    #region Implementation of INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            Address.BeginEdit();
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }


    #endregion

    public string FirstLine
    {
        get { return firstLine; }
        set
        {
            firstLine = value;
            OnPropertyChanged("FirstLine");
            OnPropertyChanged("FullAddress");
        }
    }


    public string SecondLine
    {
        get { return secondLine; }
        set
        {
            secondLine= value;
            OnPropertyChanged("SecondLine");
            OnPropertyChanged("FullAddress");
        }
    }

    public string FullAddress
    {
        get { return firstLine + secondLine; }
    }

假设您的类实现了INotifyPropertyChanged,那么您可以在任何属性设置器中进行通知。例如

    #region Implementation of INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            Address.BeginEdit();
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }


    #endregion

    public string FirstLine
    {
        get { return firstLine; }
        set
        {
            firstLine = value;
            OnPropertyChanged("FirstLine");
            OnPropertyChanged("FullAddress");
        }
    }


    public string SecondLine
    {
        get { return secondLine; }
        set
        {
            secondLine= value;
            OnPropertyChanged("SecondLine");
            OnPropertyChanged("FullAddress");
        }
    }

    public string FullAddress
    {
        get { return firstLine + secondLine; }
    }

试着这样做:

public class Address : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private string address1;
    public string Address1
    {
        get { return address1; }
        set
        {
            address1 = value; 
            OnPropertyChanged("Address1");
            OnPropertyChanged("FullAddress");
        }
    }

    private string address2;
    public string Address2
    {
        get { return address2; }
        set
        {
            address2 = value; 
            OnPropertyChanged("Address2");
            OnPropertyChanged("FullAddress");
        }
    }

    private string town;
    public string Town
    {
        get { return town; }
        set
        {
            town = value; 
            OnPropertyChanged("Town");
            OnPropertyChanged("FullAddress");
        }
    }

    public string FullAddress
    {
        get { return string.Format("{0}, {1}, {2}", address1, address2, town);  }
    }

    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

试着这样做:

public class Address : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private string address1;
    public string Address1
    {
        get { return address1; }
        set
        {
            address1 = value; 
            OnPropertyChanged("Address1");
            OnPropertyChanged("FullAddress");
        }
    }

    private string address2;
    public string Address2
    {
        get { return address2; }
        set
        {
            address2 = value; 
            OnPropertyChanged("Address2");
            OnPropertyChanged("FullAddress");
        }
    }

    private string town;
    public string Town
    {
        get { return town; }
        set
        {
            town = value; 
            OnPropertyChanged("Town");
            OnPropertyChanged("FullAddress");
        }
    }

    public string FullAddress
    {
        get { return string.Format("{0}, {1}, {2}", address1, address2, town);  }
    }

    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

我认为这里唯一的选择是让类的对象订阅它们自己的INPC事件,并自动更改它们的依赖属性。工作流程如下所示:

public class Address : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private string address1;
    public string Address1
    {
        get { return address1; }
        set
        {
            address1 = value; 
            OnPropertyChanged("Address1");
            OnPropertyChanged("FullAddress");
        }
    }

    private string address2;
    public string Address2
    {
        get { return address2; }
        set
        {
            address2 = value; 
            OnPropertyChanged("Address2");
            OnPropertyChanged("FullAddress");
        }
    }

    private string town;
    public string Town
    {
        get { return town; }
        set
        {
            town = value; 
            OnPropertyChanged("Town");
            OnPropertyChanged("FullAddress");
        }
    }

    public string FullAddress
    {
        get { return string.Format("{0}, {1}, {2}", address1, address2, town);  }
    }

    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}
  • 对象已创建
  • 对象订阅其自己的INPC
  • 从属属性已更改
  • INPC订阅检测到
    FullAddress
    的从属属性已更改,并更新
    FullAddress
  • FullAddress
    setter触发自己的INPC事件
  • WPF检测到
    FullAddress
    已更改并更新UI
  • 更新:示例代码

    class NotificationExample : INotifyPropertyChanged
    {
        private string firstName;
        private string lastName;
        public event PropertyChangedEventHandler PropertyChanged;
    
        public string FirstName
        {
            get { return this.firstName; }
    
            set
            {
                this.firstName = value;
                this.OnPropertyChanged("FirstName");
            }
        }
    
        public string LastName
        {
            get { return this.lastName; }
    
            set
            {
                this.lastName = value;
                this.OnPropertyChanged("LastName");
            }
        }
    
        public string FullName
        {
            get { return string.Format("{0} {1}", this.firstName, this.lastName); }
        }
    
        public NotificationExample()
        {
            this.PropertyChanged += this.NotifyIfFullNameChanged;
        }
    
        private void OnPropertyChanged(string propertyName)
        {
            var handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    
        private void NotifyIfFullNameChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "FirstName" || e.PropertyName == "LastName")
            {
                this.OnPropertyChanged("FullName");
            }
        }
    }
    

    我认为这里唯一的选择是让类的对象订阅它们自己的INPC事件,并自动更改它们的依赖属性。工作流程如下所示:

    public class Address : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        private string address1;
        public string Address1
        {
            get { return address1; }
            set
            {
                address1 = value; 
                OnPropertyChanged("Address1");
                OnPropertyChanged("FullAddress");
            }
        }
    
        private string address2;
        public string Address2
        {
            get { return address2; }
            set
            {
                address2 = value; 
                OnPropertyChanged("Address2");
                OnPropertyChanged("FullAddress");
            }
        }
    
        private string town;
        public string Town
        {
            get { return town; }
            set
            {
                town = value; 
                OnPropertyChanged("Town");
                OnPropertyChanged("FullAddress");
            }
        }
    
        public string FullAddress
        {
            get { return string.Format("{0}, {1}, {2}", address1, address2, town);  }
        }
    
        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    
  • 对象已创建
  • 对象订阅其自己的INPC
  • 从属属性已更改
  • INPC订阅检测到
    FullAddress
    的从属属性已更改,并更新
    FullAddress
  • FullAddress
    setter触发自己的INPC事件
  • WPF检测到
    FullAddress
    已更改并更新UI
  • 更新:示例代码

    class NotificationExample : INotifyPropertyChanged
    {
        private string firstName;
        private string lastName;
        public event PropertyChangedEventHandler PropertyChanged;
    
        public string FirstName
        {
            get { return this.firstName; }
    
            set
            {
                this.firstName = value;
                this.OnPropertyChanged("FirstName");
            }
        }
    
        public string LastName
        {
            get { return this.lastName; }
    
            set
            {
                this.lastName = value;
                this.OnPropertyChanged("LastName");
            }
        }
    
        public string FullName
        {
            get { return string.Format("{0} {1}", this.firstName, this.lastName); }
        }
    
        public NotificationExample()
        {
            this.PropertyChanged += this.NotifyIfFullNameChanged;
        }
    
        private void OnPropertyChanged(string propertyName)
        {
            var handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    
        private void NotifyIfFullNameChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "FirstName" || e.PropertyName == "LastName")
            {
                this.OnPropertyChanged("FullName");
            }
        }
    }
    
    您可以使用也可以不使用FullAddress属性
    编辑
    如果只需要显示完整地址,可以使用
    StringFormat

    <TextBlock>
        <TextBlock.Text>
            <MultiBinding StringFormat="{}{0}, {1}">
                <Binding Path="City"/>
                <Binding Path="Street"/>
            </MultiBinding>
        </TextBlock.Text>
    </TextBlock>
    
    
    
    如果您希望允许用户编辑整个地址字符串,然后将其拆分为多个部分,则需要实现接口

    您可以使用,也可以不使用FullAddress属性
    编辑
    如果只需要显示完整地址,可以使用
    StringFormat

    <TextBlock>
        <TextBlock.Text>
            <MultiBinding StringFormat="{}{0}, {1}">
                <Binding Path="City"/>
                <Binding Path="Street"/>
            </MultiBinding>
        </TextBlock.Text>
    </TextBlock>
    
    
    


    如果您希望允许用户编辑整个地址字符串,然后将其拆分为多个部分,那么您需要实现接口

    David感谢非常快速的响应和代码,这非常有意义。非常感谢!David感谢您的快速响应,感谢代码,这很有意义。非常感谢!迪安:我也感谢你的快速回答,伟大的人都有相同的想法。显然,你的回答和第一个答案之间的一致给我留下了深刻的印象。我会研究这段代码。我想我们是在同一时间发布的,他们都是正确的。遗憾的是,我似乎还不能投票支持任何帖子,对不起,这是我第一次在StackOverflow上发表文章。迪安,我也感谢你的快速回答,伟大的人都有同感。显然,你和第一个答案之间的一致给我留下了深刻的印象。我会研究这段代码。我想我们是在同一时间发布的,他们都是正确的。遗憾的是,我似乎还不能投票支持任何帖子,对不起,这是我第一次在StackOverflow上发布。谢谢Jon,另一个快速回答。我花了很长时间才明白这一点。我有点理解,但在步骤4中,INPC订阅如何知道FullAddress属性依赖哪些属性?我假设Object是指包含FullAddress和从属属性的类的实例,对象本身是否调用整个对象上的PropertyChanged而不是一个属性?INPC订户将是类中的私有方法。它将“知道”FullAddress依赖于什么,因为您知道它(如果e.PropertyName==“StreetAddress”等)。目标就是你所说的。PropertyChanged始终在特定属性上调用,不能在“整个对象”上调用它。要使其正常工作,FullAddress及其相关属性都需要从其setter中调用PropertyChanged。谢谢!我就快到了。。。如果我理解正确,当你说“对象订阅它自己的INPC”时,你是说在FullAddress所依赖的每个属性中,我为该属性调用PropertyChanged,但也为FullAddress属性调用OnPropertyChanged,如代码示例所示?或者,是否有一种方法可以让对象从WPF依赖属性后端获得对象内的某些内容已更改的通知?抱歉,我不确定私有方法和INPC订阅之间的链接。检查上面的代码,这就是我的意思(请参阅构造函数和
    notifyfullnamechanged
    )。这与迪恩·乔克的答案基本相同,实现方式略有不同。明白了!谢谢你的坚持,现在说得通了。很好的代码。谢谢Jon,另一个快速回答。我花了很长时间才明白这一点。我有点理解,但在步骤4中,INPC订阅如何知道FullAddress属性依赖哪些属性?我假设Object是指包含FullAddress和依赖属性的类的实例,对象本身是否在整个对象上调用PropertyChanged,而不是只调用一个适当的属性