将来自ComboBox的选定索引作为XAML数据绑定中的转换器参数传递

时间:2018-10-28 09:30:54

标签: c# xaml uwp

我的XAML:

<TextBox Text="{x:Bind local:Amount, Converter={StaticResource VolumeConverter}, Mode=TwoWay}"/>
<ComboBox x:Name="ComboBox_Amount_Unit" />

如何将ComboBox_Amount_Unit的选定索引作为参数传递给TextBox的转换器?

3 个答案:

答案 0 :(得分:1)

感谢Shakir Ahmed花费的时间帮助我提供解决方案。我几个小时前才找到解决方案:

    private double                              _BrewAmount                             = 10;
    public  double                              BrewAmount
    {
        get { return _BrewAmount; }
        set
        {
            CorrectedBrewAmount = value.ToString();
        }
    }                                                   // In database.     Holds the volume in liters, no matter the ComboBox unit selection.
    private string                              _CorrectedBrewAmount = "0";
    public  string                              CorrectedBrewAmount
    {
        get
        {
            string[] Result = Convert.VolumeFromLiterWithUnitConversion(BrewAmount, BrewAmountSelectedIndex == -1 ? AppSettings.MeasuringSystem == MeasuringSystem.Systems[MeasuringSystem.Metric] ? LiquidUnit.Liter : LiquidUnit.Gallon : BrewAmountSelectedIndex);
            _CorrectedBrewAmount = Result[0];
            return Result[0];
        }
        set
        {
            _BrewAmount = Convert.VolumeToLiter(System.Convert.ToDouble(value), BrewAmountSelectedIndex == -1 ? AppSettings.MeasuringSystem == MeasuringSystem.Systems[MeasuringSystem.Metric] ? LiquidUnit.Liter : LiquidUnit.Gallon    : BrewAmountSelectedIndex);
            NotifyPropertyChanged("CorrectedBrewAmount");
        }
    }                                           // Not in database. The value shown in the TextBox.
    private int                                 _BrewAmountSelectedIndex = -1;
    public  int                                 BrewAmountSelectedIndex
    {
        get
        {
            return _BrewAmountSelectedIndex;
        }
        set
        {
            _BrewAmountSelectedIndex = value;
            _BrewAmount = Convert.VolumeToLiter(System.Convert.ToDouble(_CorrectedBrewAmount), value == -1 ? LiquidUnit.Liter : value);
            NotifyPropertyChanged("BrewAmountSelectedIndex");
        }
    }                                      // Not in database. The bindable selected index.

我有一些转换器作为函数,并且使用了在UI中显示和绑定的更正属性,而“真实”值在原始属性中。它看起来很复杂,但是却可以正常工作。您会看到CorrectedBrewAmount和BrewAmountSelectedindex正在设置_BrewAmount,以使BrewAmount的设置器(不带下划线)不会触发。然后,通过代码设置BrewAmount时,则会设置CorrectedBrewAmount来触发转换。

答案 1 :(得分:0)

希望对您有所帮助(未经测试):

<TextBox x:Name="myTextbox"  Text="{x:Bind local:Amount, Converter={StaticResource VolumeConverter},ConverterParameter={Binding ElementName=ComboBox_Amount_Unit,Path=SelectedIndex}, Mode=TwoWay />
<ComboBox x:Name="ComboBox_Amount_Unit" }" />

答案 2 :(得分:0)

这是达成目标的另一种方法:

<Page
    x:Class="App12.BlankPage2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App12"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Page.Resources>
        <local:VolumeConverter x:Key="cvt"/>
    </Page.Resources>
    <Grid>
        <StackPanel VerticalAlignment="Center" 
                    HorizontalAlignment="Center">
            <TextBox PlaceholderText="Input value in meter" 
                     Width="300" 
                     Text="{x:Bind InputValue, Mode=TwoWay}"/>
            <Button Content="Calculate" Click="Button_Click"/>
            <ComboBox x:Name="ComboBox_Amount_Unit" 
                      Margin="0,30,0,0" 
                      Loaded="ComboBox_Amount_Unit_Loaded">
                <ComboBox.Items>
                    <ComboBoxItem Content="mm"/>
                    <ComboBoxItem Content="cm"/>
                    <ComboBoxItem Content="M"/>
                    <ComboBoxItem Content="kM"/>
                </ComboBox.Items>
            </ComboBox>
            <TextBlock Name="outputTextBlock" 
                       FontSize="25" 
                       Text="{x:Bind Volume, Mode=OneWay, Converter={StaticResource cvt}}"/>
        </StackPanel>
    </Grid>
</Page>



    public sealed partial class BlankPage2 : Page, INotifyPropertyChanged
        {
            public static BlankPage2 Current;

            public BlankPage2()
            {
                this.InitializeComponent();
                Current = this;
            }



            double _volume; 

            int _inputValue;

            public double Volume
            {
                get { return _volume; }
                set { _volume = value; RaisePropertyChanged(); }
            }

            public int InputValue
            {
                get { return _inputValue; }
                set { _inputValue = value; }
            }

            public int getIndex()
            {
                return ComboBox_Amount_Unit.SelectedIndex;
            }


            public event PropertyChangedEventHandler PropertyChanged;

            void RaisePropertyChanged([CallerMemberName]string name = null)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(name));
                }
            }

            private void ComboBox_Amount_Unit_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                if ((sender as ComboBox).SelectedIndex == 0)
                {
                    Volume = InputValue * 1000000000;
                }
                else if ((sender as ComboBox).SelectedIndex == 1)
                {
                    Volume = InputValue * 1000000;
                }
                else if ((sender as ComboBox).SelectedIndex == 2)
                {
                    Volume = InputValue;
                }
                else if ((sender as ComboBox).SelectedIndex == 3)
                {
                    Volume = InputValue / 1000000000;
                }
                else Volume = InputValue;
            }

            private void ComboBox_Amount_Unit_Loaded(object sender, RoutedEventArgs e)
            {
                ComboBox_Amount_Unit.SelectedIndex = 0;
                ComboBox_Amount_Unit.SelectionChanged += ComboBox_Amount_Unit_SelectionChanged;
            }

            private void Button_Click(object sender, RoutedEventArgs e)
            {
                if (ComboBox_Amount_Unit.SelectedIndex == 0)
                {
                    Volume = InputValue * 1000000000;
                }
                else if (ComboBox_Amount_Unit.SelectedIndex == 1)
                {
                    Volume = InputValue * 1000000;
                }
                else if (ComboBox_Amount_Unit.SelectedIndex == 2)
                {
                    Volume = InputValue;
                }
                else if (ComboBox_Amount_Unit.SelectedIndex == 3)
                {
                    Volume = InputValue / 1000000000;
                }
                else Volume = InputValue;
            }
        }


    public class VolumeConverter: IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, string language)
            {
                double val = (double)value;

                if (val == 0.0) return "";

                int index = BlankPage2.Current.getIndex();

                if(index == 0)
                {
                    return val.ToString() + " " + "mm";
                }
                else if(index == 1)
                {
                    return val.ToString() + " " + "cm";
                }
                else if(index == 2)
                {
                    return val.ToString() + " " + "m";
                }
                else if (index == 3)
                {
                    return val.ToString() + " " + "km";
                }

                return val.ToString();
            }

            public object ConvertBack(object value, Type targetType, object parameter, string language)
            {
                throw new NotImplementedException();
            }
        }