简体   繁体   English

WPF:更改所有数据绑定的路径

[英]WPF: Changing paths of all databindings

I am trying to change all the databindings in a window when a user clicks on a button. 我试图在用户单击按钮时更改窗口中的所有数据绑定。 Note: the following code is pseudo. 注意:以下代码是伪代码。

Assuming we have a class called sensor: 假设我们有一个名为sensor的类:

public class Sensor : INotifyPropertyChanged {
  public int HighVal {get; set;}
  public int LowVal {get; set;}
}

And the following model to which we bind: 以及我们绑定到的以下模型:

public class SomeModel {
  public Sensor MovementSensor {get; set;}
  public Sensor TemperatureSensor {get; set;}
  public Sensor BarometerSensor {get; set;}
}

In my xaml, I would like to bind in the following way: 在我的xaml中,我想通过以下方式进行绑定:

<TextBox Text="{Binding MyModel.MovementSensor.HighVal}"/>
<TextBlock Text="{Binding MyModel.BarometerSensor.HighVal}"/>

I would like to have a button (or something similar) that upon clicking, will change all databindings' path from HighVal to LowVal, eg 我想有一个按钮(或类似的东西),单击后会将所有数据绑定的路径从HighVal更改为LowVal,例如

<TextBox Text="{Binding MyModel.MovementSensor.LowVal}"/>
<TextBlock Text="{Binding MyModel.BarometerSensor.LowVal}"/>

Is there an elegant way to perform this without iterating over all databindings in the window? 有没有一种优雅的方法可以执行此操作而不迭代窗口中的所有数据绑定?

Thanks! 谢谢!

You could use a MultiBinding that is connected with the two values of the sensor and a third property to determine the current value: 您可以使用与传感器的两个值和第三个属性关联的MultiBinding来确定当前值:

<TextBlock>
    <TextBlock.Resources>
        <y:SensorValueConverter x:Key="SVC"></y:SensorValueConverter>
    </TextBlock.Resources>
    <TextBlock.Text>
        <MultiBinding Converter="{StaticResource SVC}">            
            <Binding Path="MyModel.BarometerSensor.HighVal" />
            <Binding Path="MyModel.BarometerSensor.LowVal" />
            <Binding Path="MyModel.BarometerSensor.SelectedVal" />    
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

In the Windows tag you specify the namespace of the converter, but you have to replace the "YOUR-PROJECTNAME" placeholder: 在Windows标记中,指定转换器的名称空间,但必须替换“ YOUR-PROJECTNAME”占位符:

<Window x:Class="..."
        ...
        xmlns:y="clr-namespace:YOUR-PROJECTNAME">

I have extended the class Sensor by the property SelectedVal which stores the value that should be shown in the TextBox. 我已经通过属性SelectedVal扩展了Sensor类,该属性存储了应该在TextBox中显示的值。 Changing it to "High" or to "Low" will immediatly update the Binding of the TextBox. 将其更改为“高”或“低”将立即更新TextBox的绑定。

public enum SelectedValue
{
    High,
    Low
}

public class Sensor : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;       

    public int HighVal {get; set;}
    public int LowVal {get; set;}

    SelectedValue selval = SelectedValue.High;
    public SelectedValue SelectedVal
    {
        get
        {
            return selval;
        }
        set
        {
            selval = value;
            PropertyChanged(this, new PropertyChangedEventArgs("SelectedVal"));
        }
    }
}

And now the most important part, the ValueConverter for the Binding that will choose the right value depending on the state of SelectedVal (class CultureInfo is the System.Globalization namespace): 现在最重要的部分是Binding的ValueConverter,它将根据SelectedVal的状态选择正确的值( CultureInfo类是System.Globalization命名空间):

public class SensorValueConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {         
        SelectedValue val = (SelectedValue)values[2];

        if (val == SelectedValue.High)
        {
            return values[0].ToString();
        }
        else
        {
            return values[1].ToString();
        }
    }

    public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
    {

        throw new NotImplementedException();

    }
}

To change the selected value of the sensor, you need to modify the SelectedVal property: 要更改传感器的选定值,您需要修改SelectedVal属性:

MyModel.BarometerSensor.SelectedVal = SelectedValue.Low

UPDATE: 更新:
To assign the binding to many Elements, a style can be defined in a separate file (Styles.xaml): 要将绑定分配给许多Elements,可以在单独的文件(Styles.xaml)中定义样式:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:y="clr-namespace:YOUR-PROJECTNAME">

    <y:SensorValueConverter x:Key="SVC"></y:SensorValueConverter>
    <Style x:Key="ValStyle" TargetType="TextBlock">
        <Setter Property="Text">
            <Setter.Value>
                <MultiBinding Converter="{StaticResource SVC}">
                    <Binding Path="MyModel.BarometerSensor.HighVal" />
                    <Binding Path="MyModel.BarometerSensor.LowVal" />
                    <Binding Path="MyModel.BarometerSensor.SelectedVal" />
                </MultiBinding>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

To use this Style from other windows put simply this line in the resources of the window: 要在其他窗口中使用此样式,只需将以下行放入窗口的资源中:

<ResourceDictionary Source="Styles.xaml"></ResourceDictionary>

Finally you need to assign the created style to all TextBlocks that should display the values: 最后,您需要将创建的样式分配给应该显示值的所有TextBlock:

<TextBlock Style="{StaticResource ValStyle}"></TextBlock>

For a sensor with only one property, you can create another style in Styles.xaml that has to be bound to only one property: 对于仅具有一个属性的传感器,可以在Styles.xaml中创建必须绑定到仅一个属性的另一种样式:

<Style x:Key="SpecialValStyle" TargetType="TextBlock">
    <Setter Property="Text">            
        <Binding Path="MyModel.BarometerSensor.HighVal" />
    </Setter>
</Style>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM