ฉันใช้BooleanToVisibilityConverter
ใน WPF ผูกพันทรัพย์สินของการควบคุมที่Visibility
Boolean
นี้ทำงานได้ดี แต่ฉันต้องการหนึ่งของการควบคุมเพื่อซ่อนถ้าบูลเป็นและแสดงถ้ามันtrue
false
ฉันใช้BooleanToVisibilityConverter
ใน WPF ผูกพันทรัพย์สินของการควบคุมที่Visibility
Boolean
นี้ทำงานได้ดี แต่ฉันต้องการหนึ่งของการควบคุมเพื่อซ่อนถ้าบูลเป็นและแสดงถ้ามันtrue
false
คำตอบ:
ติดตั้ง IValueConverter ของคุณเอง การใช้งานตัวอย่างอยู่ที่
http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx
ในวิธีการแปลงให้คืนค่าที่คุณต้องการแทนที่จะเป็นค่าเริ่มต้น
คุณสามารถบรรลุเป้าหมายเดียวกันได้โดยใช้IValueConverter
การนำไปใช้ทั่วไปที่สามารถแปลงค่าบูลีนเป็นค่าเป้าหมายที่กำหนดค่าได้จริงและเท็จ ด้านล่างนี้เป็นหนึ่งในการติดตั้งดังกล่าว:
public class BooleanConverter<T> : IValueConverter
{
public BooleanConverter(T trueValue, T falseValue)
{
True = trueValue;
False = falseValue;
}
public T True { get; set; }
public T False { get; set; }
public virtual object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value is bool && ((bool) value) ? True : False;
}
public virtual object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value is T && EqualityComparer<T>.Default.Equals((T) value, True);
}
}
ถัดไป subclass มันที่T
เป็นVisibility
:
public sealed class BooleanToVisibilityConverter : BooleanConverter<Visibility>
{
public BooleanToVisibilityConverter() :
base(Visibility.Visible, Visibility.Collapsed) {}
}
ในที่สุดนี่คือวิธีที่คุณสามารถใช้ BooleanToVisibilityConverter
ข้างต้นใน XAML และกำหนดค่าให้ตัวอย่างเช่นใช้Collapsed
สำหรับจริงและVisible
เท็จ:
<Application.Resources>
<app:BooleanToVisibilityConverter
x:Key="BooleanToVisibilityConverter"
True="Collapsed"
False="Visible" />
</Application.Resources>
การผกผันนี้มีประโยชน์เมื่อคุณต้องการผูกเข้ากับคุณสมบัติบูลีนที่ตั้งชื่อIsHidden
ตามต้องการIsVisible
ด้วย
Visibility
คุณสมบัติในรูปแบบมุมมองของคุณ
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
public sealed class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var flag = false;
if (value is bool)
{
flag = (bool)value;
}
else if (value is bool?)
{
var nullable = (bool?)value;
flag = nullable.GetValueOrDefault();
}
if (parameter != null)
{
if (bool.Parse((string)parameter))
{
flag = !flag;
}
}
if (flag)
{
return Visibility.Visible;
}
else
{
return Visibility.Collapsed;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var back = ((value is Visibility) && (((Visibility)value) == Visibility.Visible));
if (parameter != null)
{
if ((bool)parameter)
{
back = !back;
}
}
return back;
}
}
จากนั้นผ่านจริงหรือเท็จเป็น ConverterParameter
<Grid.Visibility>
<Binding Path="IsYesNoButtonSetVisible" Converter="{StaticResource booleanToVisibilityConverter}" ConverterParameter="true"/>
</Grid.Visibility>
else if (value is bool?)
ส่วน ReSharper บอกฉันว่า "การแสดงออกเป็นเท็จเสมอ" นอกจากนี้ส่วนหนึ่งสามารถเขียนรัดกุมมากเป็นif (flag)
return flag ? Visibility.Visible : Visibility.Collapsed;
var nullable = (bool?)value; flag = nullable.GetValueOrDefault();
สามารถทำให้สั้นและเรียบง่ายมาก:flag = (bool?)value ?? false;
เขียนของคุณเองเป็นทางออกที่ดีที่สุดสำหรับตอนนี้ นี่คือตัวอย่างของตัวแปลงที่สามารถทำได้ทั้งแบบปกติและแบบคว่ำ หากคุณมีปัญหาใด ๆ กับสิ่งนี้เพียงแค่ถาม
[ValueConversion(typeof(bool), typeof(Visibility))]
public class InvertableBooleanToVisibilityConverter : IValueConverter
{
enum Parameters
{
Normal, Inverted
}
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
var boolValue = (bool)value;
var direction = (Parameters)Enum.Parse(typeof(Parameters), (string)parameter);
if(direction == Parameters.Inverted)
return !boolValue? Visibility.Visible : Visibility.Collapsed;
return boolValue? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
return null;
}
}
<UserControl.Resources>
<Converters:InvertableBooleanToVisibilityConverter x:Key="_Converter"/>
</UserControl.Resources>
<Button Visibility="{Binding IsRunning, Converter={StaticResource _Converter}, ConverterParameter=Inverted}">Start</Button>
BooleanToVisibilityConverter
Parameter direction = Parameter.Normal; if (parameter != null) direction = (Parameter)Enum.Parse(typeof(Parameter), (string)parameter);
นอกจากนี้ยังมีโปรเจ็กต์WPF Convertersบน Codeplex ในเอกสารของพวกเขาพวกเขาบอกว่าคุณสามารถใช้MapConverterเพื่อแปลงจากการมองเห็นการแจงเป็นบูล
<Label>
<Label.Visible>
<Binding Path="IsVisible">
<Binding.Converter>
<con:MapConverter>
<con:Mapping From="True" To="{x:Static Visibility.Visible}"/>
<con:Mapping From="False" To="{x:Static Visibility.Hidden}"/>
</con:MapConverter>
</Binding.Converter>
</Binding>
</Label.Visible>
</Label>
อีกวิธีหนึ่งในการผูกค่า Boolean ViewModel (IsButtonVisible) ด้วยคุณสมบัติการควบคุมการมองเห็น xaml ไม่มีการเข้ารหัสไม่มีการแปลงเพียงแค่จัดแต่งทรงผม
<Style TargetType={x:Type Button} x:Key="HideShow">
<Style.Triggers>
<DataTrigger Binding="{Binding IsButtonVisible}" Value="False">
<Setter Property="Visibility" Value="Hidden"/>
</DataTrigger>
</Style.Triggers>
</Style>
<Button Style="{StaticResource HideShow}">Hello</Button>
หรือวิธีขี้เกียจที่แท้จริงเพียงแค่ใช้ประโยชน์จากสิ่งที่มีอยู่แล้วและพลิกมัน:
public class InverseBooleanToVisibilityConverter : IValueConverter
{
private BooleanToVisibilityConverter _converter = new BooleanToVisibilityConverter();
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var result = _converter.Convert(value, targetType, parameter, culture) as Visibility?;
return result == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var result = _converter.ConvertBack(value, targetType, parameter, culture) as bool?;
return result == true ? false : true;
}
}
หากคุณไม่ชอบการเขียนตัวแปลงที่กำหนดเองคุณสามารถใช้ทริกเกอร์ข้อมูลเพื่อแก้ปัญหานี้:
<Style.Triggers>
<DataTrigger Binding="{Binding YourBinaryOption}" Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
<DataTrigger Binding="{Binding YourBinaryOption}" Value="False">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
ฉันเพิ่งโพสต์ข้อความนี้ ฉันใช้ความคิดแบบเดียวกันกับที่ Michael Hohlios ทำ เฉพาะฉันใช้คุณสมบัติแทนการใช้ "พารามิเตอร์พารามิเตอร์"
การมองเห็นการเชื่อมโยงกับค่าบูลใน WPF
การใช้คุณสมบัติทำให้อ่านง่ายขึ้นในความคิดของฉัน
<local:BoolToVisibleOrHidden x:Key="BoolToVisConverter" Collapse="True" Reverse="True" />
นี่คือสิ่งที่ฉันเขียนและใช้บ่อยมาก มันใช้พารามิเตอร์ตัวแปลงบูลีนที่บ่งชี้ว่าจะกลับค่าหรือไม่แล้วใช้ XOR เพื่อดำเนินการปฏิเสธ:
[ValueConversion(typeof(bool), typeof(System.Windows.Visibility))]
public class BooleanVisibilityConverter : IValueConverter
{
System.Windows.Visibility _visibilityWhenFalse = System.Windows.Visibility.Collapsed;
/// <summary>
/// Gets or sets the <see cref="System.Windows.Visibility"/> value to use when the value is false. Defaults to collapsed.
/// </summary>
public System.Windows.Visibility VisibilityWhenFalse
{
get { return _visibilityWhenFalse; }
set { _visibilityWhenFalse = value; }
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool negateValue;
Boolean.TryParse(parameter as string, out negateValue);
bool val = negateValue ^ System.Convert.ToBoolean(value); //Negate the value when negateValue is true using XOR
return val ? System.Windows.Visibility.Visible : _visibilityWhenFalse;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
bool negateValue;
Boolean.TryParse(parameter as string, out negateValue);
if ((System.Windows.Visibility)value == System.Windows.Visibility.Visible)
return true ^ negateValue;
else
return false ^ negateValue;
}
}
นี่คือตารางความจริง XOR สำหรับการอ้างอิง:
XOR
x y XOR
---------
0 0 0
0 1 1
1 0 1
1 1 0
ฉันกำลังมองหาคำตอบทั่วไป แต่ไม่สามารถหาได้ ฉันเขียนตัวแปลงที่อาจช่วยผู้อื่น
มันขึ้นอยู่กับข้อเท็จจริงที่ว่าเราต้องแยกความแตกต่างหกกรณี:
นี่คือการดำเนินการของฉันสำหรับ 4 รายแรก:
[ValueConversion(typeof(bool), typeof(Visibility))]
public class BooleanToVisibilityConverter : IValueConverter
{
enum Types
{
/// <summary>
/// True to Visible, False to Collapsed
/// </summary>
t2v_f2c,
/// <summary>
/// True to Visible, False to Hidden
/// </summary>
t2v_f2h,
/// <summary>
/// True to Collapsed, False to Visible
/// </summary>
t2c_f2v,
/// <summary>
/// True to Hidden, False to Visible
/// </summary>
t2h_f2v,
}
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
var b = (bool)value;
string p = (string)parameter;
var type = (Types)Enum.Parse(typeof(Types), (string)parameter);
switch (type)
{
case Types.t2v_f2c:
return b ? Visibility.Visible : Visibility.Collapsed;
case Types.t2v_f2h:
return b ? Visibility.Visible : Visibility.Hidden;
case Types.t2c_f2v:
return b ? Visibility.Collapsed : Visibility.Visible;
case Types.t2h_f2v:
return b ? Visibility.Hidden : Visibility.Visible;
}
throw new NotImplementedException();
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
var v = (Visibility)value;
string p = (string)parameter;
var type = (Types)Enum.Parse(typeof(Types), (string)parameter);
switch (type)
{
case Types.t2v_f2c:
if (v == Visibility.Visible)
return true;
else if (v == Visibility.Collapsed)
return false;
break;
case Types.t2v_f2h:
if (v == Visibility.Visible)
return true;
else if (v == Visibility.Hidden)
return false;
break;
case Types.t2c_f2v:
if (v == Visibility.Visible)
return false;
else if (v == Visibility.Collapsed)
return true;
break;
case Types.t2h_f2v:
if (v == Visibility.Visible)
return false;
else if (v == Visibility.Hidden)
return true;
break;
}
throw new InvalidOperationException();
}
}
ตัวอย่าง:
Visibility="{Binding HasItems, Converter={StaticResource BooleanToVisibilityConverter}, ConverterParameter='t2v_f2c'}"
ฉันคิดว่าพารามิเตอร์จำง่าย
หวังว่าจะช่วยใครซักคน
คุณสามารถใช้QuickConverter QuickConverter
ด้วย QuickConverter คุณสามารถเขียนลอจิกแบบอินไลน์ด้วย BindingExpression ของคุณ
นี่คือตัวแปลง BooleanToVisibility แบบกลับด้าน:
Visibility="{qc:Binding '!$P ? Visibility.Visible : Visibility.Collapsed', P={Binding Example}}"
คุณสามารถเพิ่ม QuickConverter ผ่าน NuGet ดูเอกสารประกอบสำหรับการตั้งค่า ลิงก์: https://quickconverter.codeplex.com/
เขียนการแปลงของคุณเอง
public class ReverseBooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
// your converter code here
}
}
เวอร์ชันทางเดียวแบบง่ายซึ่งสามารถใช้ดังนี้:
Visibility="{Binding IsHidden, Converter={x:Static Ui:Converters.BooleanToVisibility}, ConverterParameter=true}
สามารถนำไปใช้เช่นนี้:
public class BooleanToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var invert = false;
if (parameter != null)
{
invert = Boolean.Parse(parameter.ToString());
}
var booleanValue = (bool) value;
return ((booleanValue && !invert) || (!booleanValue && invert))
? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
แปลงทุกอย่างเป็นทุกอย่าง (บูล, สตริง, enum, ฯลฯ ):
public class EverythingConverterValue
{
public object ConditionValue { get; set; }
public object ResultValue { get; set; }
}
public class EverythingConverterList : List<EverythingConverterValue>
{
}
public class EverythingConverter : IValueConverter
{
public EverythingConverterList Conditions { get; set; } = new EverythingConverterList();
public object NullResultValue { get; set; }
public object NullBackValue { get; set; }
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
return Conditions.Where(x => x.ConditionValue.Equals(value)).Select(x => x.ResultValue).FirstOrDefault() ?? NullResultValue;
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
return Conditions.Where(x => x.ResultValue.Equals(value)).Select(x => x.ConditionValue).FirstOrDefault() ?? NullBackValue;
}
}
ตัวอย่าง XAML:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:conv="clr-namespace:MvvmGo.Converters;assembly=MvvmGo.WindowsWPF"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<conv:EverythingConverter x:Key="BooleanToVisibilityConverter">
<conv:EverythingConverter.Conditions>
<conv:EverythingConverterValue ResultValue="{x:Static Visibility.Visible}">
<conv:EverythingConverterValue.ConditionValue>
<sys:Boolean>True</sys:Boolean>
</conv:EverythingConverterValue.ConditionValue>
</conv:EverythingConverterValue>
<conv:EverythingConverterValue ResultValue="{x:Static Visibility.Collapsed}">
<conv:EverythingConverterValue.ConditionValue>
<sys:Boolean>False</sys:Boolean>
</conv:EverythingConverterValue.ConditionValue>
</conv:EverythingConverterValue>
</conv:EverythingConverter.Conditions>
</conv:EverythingConverter>
<conv:EverythingConverter x:Key="InvertBooleanToVisibilityConverter">
<conv:EverythingConverter.Conditions>
<conv:EverythingConverterValue ResultValue="{x:Static Visibility.Visible}">
<conv:EverythingConverterValue.ConditionValue>
<sys:Boolean>False</sys:Boolean>
</conv:EverythingConverterValue.ConditionValue>
</conv:EverythingConverterValue>
<conv:EverythingConverterValue ResultValue="{x:Static Visibility.Collapsed}">
<conv:EverythingConverterValue.ConditionValue>
<sys:Boolean>True</sys:Boolean>
</conv:EverythingConverterValue.ConditionValue>
</conv:EverythingConverterValue>
</conv:EverythingConverter.Conditions>
</conv:EverythingConverter>
<conv:EverythingConverter x:Key="MarriedConverter" NullResultValue="Single">
<conv:EverythingConverter.Conditions>
<conv:EverythingConverterValue ResultValue="Married">
<conv:EverythingConverterValue.ConditionValue>
<sys:Boolean>True</sys:Boolean>
</conv:EverythingConverterValue.ConditionValue>
</conv:EverythingConverterValue>
<conv:EverythingConverterValue ResultValue="Single">
<conv:EverythingConverterValue.ConditionValue>
<sys:Boolean>False</sys:Boolean>
</conv:EverythingConverterValue.ConditionValue>
</conv:EverythingConverterValue>
</conv:EverythingConverter.Conditions>
<conv:EverythingConverter.NullBackValue>
<sys:Boolean>False</sys:Boolean>
</conv:EverythingConverter.NullBackValue>
</conv:EverythingConverter>
แทนที่จะเขียนรหัสของคุณเอง / สร้างใหม่พิจารณาใช้CalcBinding :
Automatic two way convertion of bool expression to Visibility and back if target property has such type: description
<Button Visibility="{c:Binding !IsChecked}" />
<Button Visibility="{c:Binding IsChecked, FalseToVisibility=Hidden}" />
CalcBinding ยังมีประโยชน์มากสำหรับสถานการณ์อื่น ๆ อีกมากมาย
ฉันรู้ว่านี่เป็นวันที่ แต่คุณไม่จำเป็นต้องใช้สิ่งใดอีกเลย
สิ่งที่ฉันทำคือลบล้างมูลค่าของทรัพย์สินเช่นนี้:
<!-- XAML code -->
<StackPanel Name="x" Visibility="{Binding Path=Specials, ElementName=MyWindow, Converter={StaticResource BooleanToVisibilityConverter}}"></StackPanel>
<StackPanel Name="y" Visibility="{Binding Path=NotSpecials, ElementName=MyWindow, Converter={StaticResource BooleanToVisibilityConverter}}"></StackPanel>
....
//Code behind
public bool Specials
{
get { return (bool) GetValue(SpecialsProperty); }
set
{
NotSpecials= !value;
SetValue(SpecialsProperty, value);
}
}
public bool NotSpecials
{
get { return (bool) GetValue(NotSpecialsProperty); }
set { SetValue(NotSpecialsProperty, value); }
}
และใช้งานได้ดี!
ฉันพลาดอะไรไปรึเปล่า?