什麼是一組3個單選按鈕綁定到值1,2,或3 int類型的屬性的最簡單的方法?簡單的WPF RadioButton綁定?
回答
其實,利用轉換器一樣,打破兩正如我上面所說的,你也不能在枚舉中使用它。更好的方式來做到這一點是針對一個ListBox簡單的款式,就像這樣:
注:相反的是DrWPF.com在他們的例子說明,做不把ContentPresenter的單選按鈕內,否則如果添加一個包含按鈕或其他內容的項目,您將無法設置焦點或與其進行交互。這項技術解決了這個問題。此外,您需要處理文本的灰色以及刪除標籤上的邊距,否則將無法正確呈現。這種風格也適合你。
<Style x:Key="RadioButtonListItem" TargetType="{x:Type ListBoxItem}" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<DockPanel LastChildFill="True" Background="{TemplateBinding Background}" HorizontalAlignment="Stretch" VerticalAlignment="Center" >
<RadioButton IsChecked="{TemplateBinding IsSelected}" Focusable="False" IsHitTestVisible="False" VerticalAlignment="Center" Margin="0,0,4,0" />
<ContentPresenter
Content = "{TemplateBinding ContentControl.Content}"
ContentTemplate = "{TemplateBinding ContentControl.ContentTemplate}"
ContentStringFormat = "{TemplateBinding ContentControl.ContentStringFormat}"
HorizontalAlignment = "{TemplateBinding Control.HorizontalContentAlignment}"
VerticalAlignment = "{TemplateBinding Control.VerticalContentAlignment}"
SnapsToDevicePixels = "{TemplateBinding UIElement.SnapsToDevicePixels}" />
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="RadioButtonList" TargetType="ListBox">
<Style.Resources>
<Style TargetType="Label">
<Setter Property="Padding" Value="0" />
</Style>
</Style.Resources>
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="ItemContainerStyle" Value="{StaticResource RadioButtonListItem}" />
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextBlock.Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="HorizontalRadioButtonList" BasedOn="{StaticResource RadioButtonList}" TargetType="ListBox">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel Background="Transparent" Orientation="Horizontal" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
你現在有單選按鈕的外觀和感覺,但你可以做雙向綁定,你可以使用一個枚舉。以下是如何...
<ListBox Style="{StaticResource RadioButtonList}"
SelectedValue="{Binding SomeVal}"
SelectedValuePath="Tag">
<ListBoxItem Tag="{x:Static l:MyEnum.SomeOption}" >Some option</ListBoxItem>
<ListBoxItem Tag="{x:Static l:MyEnum.SomeOtherOption}">Some other option</ListBoxItem>
<ListBoxItem Tag="{x:Static l:MyEnum.YetAnother}" >Yet another option</ListBoxItem>
</ListBox>
而且,因爲我們明確地分離出來是tragets的ListBoxItem中,而不是把它內嵌的風格,再次作爲其他例子已經表明,你現在可以創建一個新的風格斷它根據每個項目(如間距)定製事物。 (如果你只是嘗試目標ListBoxItem的配合鍵樣式將覆蓋通用的控制目標,這是行不通的。)
這裏的推杆6保證金每個項目的上面和下面的一個例子。 (請注意,您如何有通過ItemContainerStyle屬性明確應用的樣式,而不是簡單地爲理由ListBox的資源區段定位ListBoxItem的上述說明。)
<Window.Resources>
<Style x:Key="SpacedRadioButtonListItem" TargetType="ListBoxItem" BasedOn="{StaticResource RadioButtonListItem}">
<Setter Property="Margin" Value="0,6" />
</Style>
</Window.Resources>
<ListBox Style="{StaticResource RadioButtonList}"
ItemContainerStyle="{StaticResource SpacedRadioButtonListItem}"
SelectedValue="{Binding SomeVal}"
SelectedValuePath="Tag">
<ListBoxItem Tag="{x:Static l:MyEnum.SomeOption}" >Some option</ListBoxItem>
<ListBoxItem Tag="{x:Static l:MyEnum.SomeOtherOption}">Some other option</ListBoxItem>
<ListBoxItem Tag="{x:Static l:MyEnum.YetAnother}" >Ter another option</ListBoxItem>
</ListBox>
希望這會有所幫助,當然,如果你喜歡這個,請標記爲已接受或投票給我! :)
+1,但如果這是'將3個單選按鈕綁定到值爲1,2或3的int類型屬性的最簡單方法,那麼它對WPF來說並不是很好。它真的超越了我,爲什麼他們使事情變得簡單,讓事情變得如此頭痛難以且不必要的複雜 – 2012-04-30 13:36:44
這實際上不僅僅是因爲它設計了一個列表框,而是一個單一的控件,所以綁定的工作原理如此簡單(一旦你獲得通過瘋狂的設置。)但是,我同意RadioButton類肯定有一些綁定的缺點。當然,你可以用代碼隱藏的方式做得更簡單,但是在這裏這種方式,你只需要做一次樣式等,然後稍後使用它就容易多了。 – MarqueIV 2012-04-30 15:43:54
OMG,簡單嗎?儘管對你的回答和努力給予了應有的尊重,但稱這種「簡單的風格」卻相當牽強,不是嗎? WPF和Winforms的核心思想和感知優勢不是更好的數據綁定?在WPF投放市場多年之後,一個簡單的單選按鈕(和單選按鈕分組)如何破壞綁定是我無法理解的。對MS感到羞恥。 – 2015-03-18 10:49:23
我想出了一個簡單的解決方案。
我有一個model.cs類:
private int _isSuccess;
public int IsSuccess { get { return _isSuccess; } set { _isSuccess = value; } }
我Window1.xaml.cs用的DataContext設置爲model.cs文件。 XAML中包含了單選按鈕:
<RadioButton IsChecked="{Binding Path=IsSuccess, Converter={StaticResource radioBoolToIntConverter}, ConverterParameter=1}" Content="one" />
<RadioButton IsChecked="{Binding Path=IsSuccess, Converter={StaticResource radioBoolToIntConverter}, ConverterParameter=2}" Content="two" />
<RadioButton IsChecked="{Binding Path=IsSuccess, Converter={StaticResource radioBoolToIntConverter}, ConverterParameter=3}" Content="three" />
這裏是我的轉換器:
public class RadioBoolToIntConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
int integer = (int)value;
if (integer==int.Parse(parameter.ToString()))
return true;
else
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return parameter;
}
}
當然,在窗口1的資源:
<Window.Resources>
<local:RadioBoolToIntConverter x:Key="radioBoolToIntConverter" />
</Window.Resources>
這個轉換器的問題是它不適用於枚舉作爲參數(你的ToString()調用死亡。)看到我的答案在下面。 – MarqueIV 2010-11-07 21:43:38
你只需要改變你的轉換器來解析枚舉 – 2012-04-12 21:05:52
再一次,這不適用於雙向綁定。 'Convert Back'調用會嘗試讓多個事物設置不同的綁定值,在這種情況下,當您嘗試將屬性IsSuccess設置爲一個值時遇到競爭條件,而另一個嘗試將其設置爲不同的值。這是這種方法的問題。當然,這是更少的代碼,但你仍然有單獨的控件都試圖改變一個屬性。 (記住,當你選擇一個單選按鈕時,它會取消選擇另一個單選按鈕,因此會有兩個更改。) – MarqueIV 2012-07-14 00:38:20
我知道它的方式方法姍姍來遲,但我有一個替代的解決方案,這是更輕,更簡單。從System.Windows.Controls.RadioButton
派生類並聲明兩個依賴項屬性RadioValue
和RadioBinding
。然後在類代碼,重寫OnChecked
並設置RadioBinding
屬性值的RadioValue
屬性值。在另一方向,陷阱使用回調改變爲RadioBinding
屬性,並且如果新的值等於RadioValue
屬性的值,其IsChecked
屬性設置爲true
。
下面的代碼:
public class MyRadioButton : RadioButton
{
public object RadioValue
{
get { return (object)GetValue(RadioValueProperty); }
set { SetValue(RadioValueProperty, value); }
}
// Using a DependencyProperty as the backing store for RadioValue.
This enables animation, styling, binding, etc...
public static readonly DependencyProperty RadioValueProperty =
DependencyProperty.Register(
"RadioValue",
typeof(object),
typeof(MyRadioButton),
new UIPropertyMetadata(null));
public object RadioBinding
{
get { return (object)GetValue(RadioBindingProperty); }
set { SetValue(RadioBindingProperty, value); }
}
// Using a DependencyProperty as the backing store for RadioBinding.
This enables animation, styling, binding, etc...
public static readonly DependencyProperty RadioBindingProperty =
DependencyProperty.Register(
"RadioBinding",
typeof(object),
typeof(MyRadioButton),
new FrameworkPropertyMetadata(
null,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
OnRadioBindingChanged));
private static void OnRadioBindingChanged(
DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
MyRadioButton rb = (MyRadioButton)d;
if (rb.RadioValue.Equals(e.NewValue))
rb.SetCurrentValue(RadioButton.IsCheckedProperty, true);
}
protected override void OnChecked(RoutedEventArgs e)
{
base.OnChecked(e);
SetCurrentValue(RadioBindingProperty, RadioValue);
}
}
XAML用法:
<my:MyRadioButton GroupName="grp1" Content="Value 1"
RadioValue="val1" RadioBinding="{Binding SelectedValue}"/>
<my:MyRadioButton GroupName="grp1" Content="Value 2"
RadioValue="val2" RadioBinding="{Binding SelectedValue}"/>
<my:MyRadioButton GroupName="grp1" Content="Value 3"
RadioValue="val3" RadioBinding="{Binding SelectedValue}"/>
<my:MyRadioButton GroupName="grp1" Content="Value 4"
RadioValue="val4" RadioBinding="{Binding SelectedValue}"/>
希望有人認爲這有用的這段時間:)
我很驚訝,沒有人想出了這個類。的解決方案將其綁定到bool陣列上。它可能不是最乾淨的,但它可以很輕鬆的使用:
private bool[] _modeArray = new bool[] { true, false, false};
public bool[] ModeArray
{
get { return _modeArray ; }
}
public int SelectedMode
{
get { return Array.IndexOf(_modeArray, true); }
}
在XAML:
<RadioButton GroupName="Mode" IsChecked="{Binding Path=ModeArray[0], Mode=TwoWay}"/>
<RadioButton GroupName="Mode" IsChecked="{Binding Path=ModeArray[1], Mode=TwoWay}"/>
<RadioButton GroupName="Mode" IsChecked="{Binding Path=ModeArray[2], Mode=TwoWay}"/>
注意:你不需要雙向綁定,如果你不想給一個默認選中。雙向綁定是這種解決方案的最大缺點。
優點:
- 無需代碼背後
- 無需額外的類(IValue轉換器)
- 無需額外枚舉
- 犯規需要的bizzare結合
- 簡單,易於瞭解
- 不違反MVVM(嘿,至少我希望如此)
我也很驚訝。此解決方案適用於那些WPF新手,只知道如何進行綁定並希望快速綁定單選按鈕。這非常簡單直接。 +1 – QuantumHive 2014-08-26 11:53:56
這是很好的,在寫出我自己的'Converter'之前,很快就會投入測試。 +1 – 2015-01-07 19:59:16
只是一個小建議:從C#6開始,你不再需要支持領域了。只需使用AutoProperty:public bool [] ModeArray {get; } = new bool [] {true,false,false}; – oopbase 2016-05-12 08:08:42
這個例子看起來有點冗長,但其意圖應該很清楚。
它在ViewModel中使用3個布爾屬性,FlagForValue1
,FlagForValue2
和FlagForValue3
。 這三個屬性中的每一個都由稱爲_intValue
的單個私人字段支持。
view(xaml)的3個單選按鈕每個綁定到視圖模型中相應的Flag屬性。這意味着顯示「值1」的單選按鈕綁定到視圖模型中的FlagForValue1
布爾屬性,其他兩個相應地綁定。
當設置在視圖模型的屬性之一(例如FlagForValue1
),它重要也提高屬性改變爲其他兩個屬性事件(例如FlagForValue2
,和FlagForValue3
),所以在UI(WPF INotifyPropertyChanged
基礎設施)可以選擇/正確取消每個單選按鈕。
private int _intValue;
public bool FlagForValue1
{
get
{
return (_intValue == 1) ? true : false;
}
set
{
_intValue = 1;
RaisePropertyChanged("FlagForValue1");
RaisePropertyChanged("FlagForValue2");
RaisePropertyChanged("FlagForValue3");
}
}
public bool FlagForValue2
{
get
{
return (_intValue == 2) ? true : false;
}
set
{
_intValue = 2;
RaisePropertyChanged("FlagForValue1");
RaisePropertyChanged("FlagForValue2");
RaisePropertyChanged("FlagForValue3");
}
}
public bool FlagForValue3
{
get
{
return (_intValue == 3) ? true : false;
}
set
{
_intValue = 3;
RaisePropertyChanged("FlagForValue1");
RaisePropertyChanged("FlagForValue2");
RaisePropertyChanged("FlagForValue3");
}
}
的XAML看起來是這樣的:
<RadioButton GroupName="Search" IsChecked="{Binding Path=FlagForValue1, Mode=TwoWay}"
>Value 1</RadioButton>
<RadioButton GroupName="Search" IsChecked="{Binding Path=FlagForValue2, Mode=TwoWay}"
>Value 2</RadioButton>
<RadioButton GroupName="Search" IsChecked="{Binding Path=FlagForValue3, Mode=TwoWay}"
>Value 3</RadioButton>
請添加一些解釋 – 2015-07-23 07:45:01
醜陋像罪,但基本上我也是這麼做的。 – 2016-10-02 05:49:34
有時可以解決它在這樣的模式: 假設你有3個布爾屬性OptionA,OptionB,OptionC中。
XAML:
<RadioButton IsChecked="{Binding OptionA}"/>
<RadioButton IsChecked="{Binding OptionB}"/>
<RadioButton IsChecked="{Binding OptionC}"/>
CODE:
private bool _optionA;
public bool OptionA
{
get { return _optionA; }
set
{
_optionA = value;
if(_optionA)
{
this.OptionB= false;
this.OptionC = false;
}
}
}
private bool _optionB;
public bool OptionB
{
get { return _optionB; }
set
{
_optionB = value;
if(_optionB)
{
this.OptionA= false;
this.OptionC = false;
}
}
}
private bool _optionC;
public bool OptionC
{
get { return _optionC; }
set
{
_optionC = value;
if(_optionC)
{
this.OptionA= false;
this.OptionB = false;
}
}
}
你的想法。 不是最乾淨的事情,但容易。
我想出瞭解決方案,使用Binding.DoNothing
從轉換器返回不會破壞雙向綁定。
public class EnumToCheckedConverter : IValueConverter
{
public Type Type { get; set; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value != null && value.GetType() == Type)
{
try
{
var parameterFlag = Enum.Parse(Type, parameter as string);
if (Equals(parameterFlag, value))
{
return true;
}
}
catch (ArgumentNullException)
{
return false;
}
catch (ArgumentException)
{
throw new NotSupportedException();
}
return false;
}
else if (value == null)
{
return false;
}
throw new NotSupportedException();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value != null && value is bool check)
{
if (check)
{
try
{
return Enum.Parse(Type, parameter as string);
}
catch(ArgumentNullException)
{
return Binding.DoNothing;
}
catch(ArgumentException)
{
return Binding.DoNothing;
}
}
return Binding.DoNothing;
}
throw new NotSupportedException();
}
}
用法:
<converters:EnumToCheckedConverter x:Key="SourceConverter" Type="{x:Type monitor:VariableValueSource}" />
單選按鈕綁定:
<RadioButton GroupName="ValueSource"
IsChecked="{Binding Source, Converter={StaticResource SourceConverter}, ConverterParameter=Function}">Function</RadioButton>
- 1. Radiobutton wpf綁定
- 2. Wpf RadioButton組綁定
- 3. WPF簡單綁定
- 4. 簡單的WPF + MVVM綁定
- 5. WPF簡單數據綁定
- 6. WPF簡單綁定問題
- 7. ItemsControl中的WPF RadioButton IsChecked綁定路徑
- 8. WPF DataGrid綁定Radiobutton列屬性
- 9. 簡單的WPF MVVM綁定問題
- 10. 簡單的WPF綁定無法工作
- 11. 將WPF單選按鈕綁定到ViewModel中的RadioButton`
- 12. WPF簡單綁定到對象屬性
- 13. WPF簡單綁定在代碼後面
- 14. WPF簡單綁定到INotifyPropertyChanged對象
- 15. 簡寫和單手WPF綁定等效
- 16. XAML雙向綁定RadioButton IsChecked
- 17. WPF中的單向綁定的簡單問題
- 18. 綁定問題與RadioButton
- 19. 簡單的綁定不工作在jQuery中的Radiobutton的IE瀏覽器
- 20. Javascript簡單綁定
- 21. 通過綁定設置WPF DependencyProperty的RadioButton控件集合
- 22. 簡單的WinJS ListView綁定
- 23. 簡單的角度綁定
- 24. 簡單的Emacs鍵綁定
- 25. 簡單綁定的問題
- 26. 簡單的綁定問題
- 27. 有沒有簡單的方法綁定到WPF中的父行?
- 28. 簡單的地方捕捉更改綁定的XML在WPF
- 29. 簡單地綁定到WPF應用程序中的類
- 30. 從ObservableCollection到DataGrid(WPF)的簡單數據綁定?
看一看這個博客條目:> [WPF單選按鈕和數據綁定(http://geekswithblogs.net /claraoscura/archive/2008/10/17/125901.aspx) – Nifle 2009-08-23 07:40:26
請看解決方案[在WPF中的RadioButton的Binding IsChecked屬性](http://pstaev.blogspot.com/2008/10/binding-ischecked-property -of.html),它就像一個魅力。原來的問題已被修復爲WPF 4.0! – 2009-11-06 15:43:14
一個更好,更通用的解決方案可以在這個答案中找到:http://stackoverflow.com/a/406798/414306 – 2012-12-28 12:54:34