2016-12-06 41 views
1

我在寻找阻止切换RadioButton的可能性,但仍然捕获Click事件。不幸地使用Enabled=falseIsHitTestVisible=false属性阻止Click事件。推迟RadioButton更改

我想实现的是:
1.用户点击RadioButton
2.从Click事件中某些方法被调用时处理程序作为参数传递,但活动RadioButton尚未更改。
3.当处理程序被调用时,根据结果我想要切换RadioButton或不。

+0

你想把委托作为参数吧?他们(代表)保存在哪里:在某些私人收藏中,或在Tag属性或每个RadioButton的某些元信息中? – EgoPingvina

+0

更确切地说,我将C++ \ CLI方法作为参数委托来调用。我将它作为来自C#类的参数方法给出。 –

回答

1

我为你简单的创建例。

不要忘记从NuGetPrism包。

我创建了三个RadioButton's,并为某些ViewModel中的Func<bool>设置了它们。在PreviewMouseDown事件触发后,我调用当前代理,这是 Tag属性。

视图模型:查看(设计师)的

namespace PostponeRadioButtonChange.Model 
{ 
    using System; 
    using System.Collections.Generic; 

    using Microsoft.Practices.Prism.Mvvm; 

    public class MainWindow : BindableBase 
    { 
     private List<Func<bool>> rbHandlers; 

     private string comment; 

     public List<Func<bool>> RbHandlers 
     { 
      get { return this.rbHandlers; } 
      private set { this.SetProperty(ref this.rbHandlers, value); } 
     } 

     public string Comment 
     { 
      get { return this.comment; } 
      set { this.SetProperty(ref this.comment, value); } 
     } 

     public MainWindow() 
     { 
      this.RbHandlers = new List<Func<bool>> 
      { 
       () => 
        { 
         this.Comment = "First RadioButton clicked"; 
         return false; // Here must be your condition for checking 
        }, 
       () => 
        { 
         this.Comment = "Second RadioButton clicked"; 
         return false; 
        }, 
       () => 
        { 
         this.Comment = "Third RadioButton clicked"; 
         return true; // For example, third not checked after click 
        } 
      }; 
     } 
    } 
} 

内容;

<StackPanel> 

    <TextBox Text="{Binding Path=Comment, Mode=OneWay}"/> 

    <RadioButton Content="First" 
       PreviewMouseDown="RadioButtonMouseDown" 
       Tag="{Binding Path=RbHandlers[0], Mode=OneTime}"/> 

    <RadioButton Content="Second" 
       PreviewMouseDown="RadioButtonMouseDown" 
       Tag="{Binding Path=RbHandlers[1], Mode=OneTime}"/> 

    <RadioButton Content="Third" 
       PreviewMouseDown="RadioButtonMouseDown" 
       Tag="{Binding Path=RbHandlers[2], Mode=OneTime}"/> 

</StackPanel> 

视图(代码隐藏):

namespace PostponeRadioButtonChange 
{ 
    using System; 
    using System.Windows; 
    using System.Windows.Controls; 
    using System.Windows.Input; 

    using VM = PostponeRadioButtonChange.Model; 

    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      this.DataContext = new VM.MainWindow(); 
     } 

     private void RadioButtonMouseDown(object sender, MouseButtonEventArgs e) 
     { 
      var rb = (sender as RadioButton); 

      if (rb == null) 
       throw new InvalidCastException("RadioButtonMouseDown only for RadioButton's"); 

      e.Handled = (rb.Tag as Func<bool>)?.Invoke() ?? false; 
     } 
    } 
} 

这是不利于最终解决方案,但作为一个例子可以帮助你。您也可以在VM中创建Command而不是事件处理程序。

我希望它能帮到你)

+1

谢谢,这远远超过我需要的,但非常有教育意义,特别是lambda数组。只需将Click事件更改为'PreviewMouseDown',然后使用'e.Handled = true'即可完成任务。我已经有一个处理程序和所有逻辑写入切换这些单选按钮。 –

+0

我很高兴能帮到你) – EgoPingvina

2

你应该处理单选按钮上的MouseDown事件,然后它会阻止隧道向下设置单选按钮被选中。

static void OnMouseDown(object sender, MouseButtonEventArgs e) 
{ 
    // if some logic... 
    e.Handled = true; 
} 
+1

这是行不通的。 首先,在wpf RadioButton中,鼠标单击事件的名称如MouseDown或PreviewMouseDown。其次,在这种情况下,您必须使用PreviewMouseDown。在MouseDown中,e.Handled = true将不起作用。 – EgoPingvina

1

使用绑定你可以把呼叫的二传手内,像这样:

XAML

<RadioButton Content="radiobutton" IsChecked="{Binding TestRadio, Mode=TwoWay}"/> 

代码

private bool _testRadio; 
    public bool TestRadio 
    { 
     get { return _testRadio; } 
     set { value = testradiohandler(); SetProperty(ref _testRadio, value); } 
    } 
    private bool testradiohandler() 
    { 
     return new Random().NextDouble() >= 0.5; 
    }