1

我正在使用 WPF 上的 MVVM 模型编写一个简单的程序。基本上,当用户单击一组单选按钮中的一个单选按钮时,它将使用新帐号更新视图模型中的属性。问题是,当我单击另一个按钮时,会为新按钮 IsChecked Binding 调用转换器,然后为上一个按钮 IsChecked 绑定运行转换器(以丢失其检查状态)。

这导致了一个问题,因为新按钮正在使用正确的帐号更新属性的值,然后当旧按钮调用转换器时,它会转换回旧值。我通过向类添加一个静态变量来破解它,如果 IsChecked 属性为假,则只需返回静态变量中的值。有没有人有更好的解决方案来短路转换器呼叫失去其选中状态的盒子。代码如下:

转换器:

class RadioToAccountConverter : IValueConverter
{
    static string myValue; //HACK TO MAKE IT WORK
    object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return parameter.ToString();
    }

    object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {

        if ((bool)value)
        {
            myValue = parameter.ToString(); // Hack to make it work
            return parameter.ToString();
        }
        return myValue; // Hack to make it work
    }
}

XAML:

                <RadioButton Foreground="HotPink" 
                             Grid.Column="0" 
                             Content="6087721" 
                             Tag="6087721"
                             IsChecked="{Binding Account, Converter={StaticResource Radio2Value}, Mode=OneWayToSource, ConverterParameter=6087721}">
                </RadioButton>

                <RadioButton Foreground="HotPink" 
                             Grid.Column="1"
                             Content="BFSC120"
                             IsChecked="{Binding Account, Converter={StaticResource Radio2Value}, Mode=OneWayToSource, ConverterParameter='BFSC120'}">
                </RadioButton>

                <RadioButton Foreground="HotPink" 
                             Grid.Column="2"
                             Content="BFSC121"
                             IsChecked="{Binding Account, Converter={StaticResource Radio2Value}, Mode=OneWayToSource, ConverterParameter=BFSC121}">
                </RadioButton>

                <RadioButton Foreground="HotPink" 
                             Grid.Column="3" 
                             Content="BFSC206" 
                             IsChecked="{Binding Account, Converter={StaticResource Radio2Value}, Mode=OneWayToSource, ConverterParameter=BFSC206}">

                </RadioButton>

财产:

    public const string AccountPropertyName = "Account";

    private string _account;

    /// <summary>
    /// Sets and gets the Account property.
    /// Changes to that property's value raise the PropertyChanged event. 
    /// </summary>
    public string Account
    {
        get
        {
            return _account;
        }

        set
        {
            if (_account == value)
            {
                return;
            }

            RaisePropertyChanging(AccountPropertyName);
            _account = value;
            RaisePropertyChanged(AccountPropertyName);
        }
    }

任何帮助是极大的赞赏。

4

2 回答 2

3

根据我的理解,您希望让用户能够从帐号列表中进行选择。您选择的演示文稿(视图)是一组单选按钮。

如果这是真的,关键部分是:您希望让用户能够从帐号列表中进行选择。这意味着您应该使用的控件是 a ListBox,因为用户应该选择适当的值之一。现在,由于您希望直观地使用单选按钮,您只需提供一个替代ItemsSource.ItemContainerStyle.


XAML:

<ListBox ItemsSource="{Binding AccountNumbers, Mode=OneWay">
  <ListBox.ItemContainerStyle>
    <Style TargetType="{x:Type ListBoxItem}">
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="{x:Type ListBoxItem}">
            <RadioButton Content="{Binding}" IsChecked="{Binding IsSelected, RelativeSource={x:Static RelativeSource.TemplatedParent}}"/>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
  </ListBox.ItemContainerStyle>
</ListBox>

请注意,您需要在 ViewModel 上添加另一个属性(我将其命名为 AccountNumbers)。例如:

public IReadOnlyCollection<string> AccountNumbers { ... }

当然,如果您需要,底层集合可以是可观察的,但这完全取决于您。

于 2013-05-23T00:25:48.680 回答
1

如果您GroupName在 each 上定义 a RadioButton,WPF 将为IsChecked您管理状态。

{Binding SomeProperty, Mode=OneWayToSource如果您希望 ViewModel 了解状态,可以使用 } 绑定状态。

解决此问题的一种方法是将每个 RadioButton 的IsChecked属性绑定到整个 ViewModel,只需将其绑定到类似

IsChecked="{Binding WholeViewModel, Mode=OneWayToSource, Converter={StaticResource MyRadioButtonConverter}, ConverterParameter=SomethingReallyUnique}"

...其中 public 属性WholeViewModelreturn this;在 getter 中执行 a 的属性。这将使您可以访问 ViewModel 和足够的信息来查询 ViewModel 以查看是否应检查单选按钮。但是,只有在GroupName DependencyProperty无法以某种方式给您想要的东西时才这样做。

要处理对按钮的单击,然后,要实际更改 ViewModel 状态,您需要在 ViewModel 中实现一个 ICommand 并将 RadioButton 的 Command 属性绑定到 {Binding ClickedCommand} 并使用您想要的任何字符串定义一个 CommandParameter。我认为,这种方法将保证与 IsChecked 状态的单向关系,从而防止您描述的事情。

如果您认为需要,我会编写一个代码示例。

于 2013-05-23T00:24:57.387 回答