我有一个Window
,其内容中有一个UserControl
和一个Button
。
现在,我想隐藏Button
中的RadioButton
,具体取决于是否选中UserControl
中的<Window x:Class="SimpleMVVMExample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="350" Width="525">
<DockPanel>
<local:uc1 x:Name="UserControl1"></local:uc1>
<Button Visibility="{Binding IsChecked,ElementName=UserControl1.rb1}"/>
</DockPanel>
</Window>
。我尝试了以下操作,但没有用。
我的窗口如下:
UserControl
<UserControl x:Class="SimpleMVVMExample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="350" Width="525">
<DockPanel>
<RadioButton x:Name="rb1" IsChecked={Binding SomeProperty}/>
</DockPanel>
</UserControl>
uc1看起来像这样:
class IdentifyUserApplicantID(generics.ListAPIView):
serializer_class = UserSerializer
permission_classes = [IsAuthenticated,]
queryset = User.objects.all()
def get_queryset(self):
queryset = User.objects.all()
applicant = self.request.query_params.get("applicant", None)
if applicant is not None:
queryset = queryset.get(applicant=applicant)
return queryset
def get(self, request):
if request.user.user_type == "2":
try:
queryset = self.get_queryset()
serializer = UserSerializer(queryset)
return Response(jsend.success({'user': serializer.data}))
except User.DoesNotExist:
return Response(jsend.success({'user': '[]'}))
else:
return Response((jsend.error("You are not authorized to perform
this action")),status=status.HTTP_403_FORBIDDEN)
答案 0 :(得分:2)
您只能绑定到UserControl中的依赖项属性,无法(afaik)那样访问UserControl中的XAML元素,因此您需要做的是在UserControl中定义一个新的Dependency属性,然后将Button的可见性与其绑定在一起。
如果您要创建一个需要向“外部XAML世界”公开信息的UserControl,我认为这就是应该这样做的方式。
UserControl1.xaml.cs:
public static readonly DependencyProperty IsRb1CheckedProperty =
DependencyProperty.Register("IsRb1Checked",
typeof(bool), typeof(UserControl1), new PropertyMetadata(default(bool)));
public bool IsRb1Checked
{
get => (bool) GetValue(IsRb1CheckedProperty);
set => SetValue(IsRb1CheckedProperty, value);
}
现在,我们需要将RadioButton绑定到该属性,但是由于UserControl的DataContext是从父级继承的,因此无法立即使用。
您可以将UserControl内的DockPanel的DataContext设置为其自身(不要更改UserControls DataContext),也可以为UserControl命名并在RadioButton绑定中使用ElementName:
让我们继续使用后一种方法,因为它更清晰。
UserControl1.xaml
<UserControl x:Class="WpfPlayground.UserControl1"
x:Name="UserControlRoot"
<RadioButton IsChecked="{Binding ElementName=UserControlRoot, Path=IsRb1Checked}"/>
</UserControl>
我直接将RadioButton绑定到IsRb1Checked,我不知道您的示例中的“ SomeProperty”是什么,但是您可以创建一个包装器属性来设置两个布尔值,甚至更好地使用Checked事件来切换IsRb1Checked。
然后在您的窗口中,请记住使用内置的BooleanToVisibilityConverter:
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter" />
</Window.Resources>
<DockPanel>
<local:UserControl1 x:Name="UserControl1"></local:UserControl1>
<Button Visibility="{Binding ElementName=UserControl1, Path=IsRb1Checked,
Converter={StaticResource BoolToVisibilityConverter}}"/>
</DockPanel>
关于MVVM的一小段评论:在这种情况下不一定有帮助。我要么被迫提供UserControl自己的ViewModel,然后在父ViewModel中实例化它,要么被赋予UserControl父ViewModel,这将阻止可重用性。最好的方法是公开依赖项属性。
答案 1 :(得分:0)
假设:IsChecked属性为布尔类型。
按钮Visibility
接受Visible, Collapsed or Hidden
的值。您需要一个布尔值到可见性转换器以使应用程序了解值true或false时需要执行的操作。
创建如下所示的资源。
<Window......>
<Window.Resources>
<BooleanToVisiblityConverter x:Key="BooleanToVisibilityConverter"/>
</Window.Resources>
.....................
....................
</Window>
如下所示更新按钮可见性。
<Button Visibility="{Binding IsChecked,ElementName=UserControl1.rb1, Converter={StaticResource BooleanToVisibilityConverter}"/>
创建一个BooleanToVisibilityConverter,如下所示。
public class BooleanToVisibilityConverter : MarkupExtension, IValueConverter
{
/// <summary>
/// This converter can be used to show, hide and collapse controls.
/// It collapse the control if <see cref="collapseIfFalse" /> is true, hides other wise by default.
/// </summary>
public object Convert(object value, Type targetType, object collapseIfFalse, CultureInfo culture)
{
var collapse = collapseIfFalse is bool && (bool)collapseIfFalse;
var visible = value is bool && (bool) value;
return visible
? Visibility.Visible
: collapse ? Visibility.Collapsed : Visibility.Hidden;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
答案 2 :(得分:0)
我了解您问过有关在XAML中执行此操作的问题,但建议您改为在/ model层后面的代码中执行。我将ischecked属性绑定到后面代码中的一个属性,并具有第二个属性,该属性检查其getter中的那个以弄清楚是否应该显示按钮。
npm ci
这样,如果启用或不启用按钮的逻辑发生变化,则可以在代码中添加更复杂的逻辑,而不必费力寻找甚至可以在XAML中完成的逻辑。这样,您还可以将“何时显示”的逻辑与如何显示分开。 XAML变得愚蠢:这就是我呈现数据的方式。有关事物如何工作的业务规则全部以C#/ sql形式进行,无论使用哪种更具表现力的(至少是IMO)语言。