c# - 使用 ViewModel 中的多个变量绑定(bind) WPF 控制可见性

标签 c# wpf xaml

我正在编写一个 WPF 用户控件,它显示一个动态生成的包含多个页面的 TabControl,每个页面又包含一个动态生成的控件列表(文本框、复选框等)。

我想根据用户是否有权查看它们来设置 TextBox、CheckBox 控件的可见性。此权限是每个控件 ViewModel ('VisiblyBy') 上的值的组合,也是整个 UserControl ViewModel ('UserRole') 的属性。我刚刚开始使用 WPF,但标准方法似乎是使用 ValueConvertor - 但是我不明白如何编写一个组合/访问不同属性(VisiblyBy 和 UserRole)的方法,因为它们存在于不同级别在我的 ViewModel 层次结构中。

这是我绑定(bind)到 ViewModel 的 XAML 的一部分:

<TabControl ItemsSource="{Binding VariableData.Pages}" SelectedIndex="0">
<!-- this is the header template-->
   <TabControl.ItemTemplate>
  <DataTemplate>
     <TextBlock Text="{Binding Title}" FontWeight="Bold"/>
  </DataTemplate>
</TabControl.ItemTemplate>
            
<!-- this is the tab content template-->
   <TabControl.ContentTemplate>
  <DataTemplate>
     <StackPanel>
        <ListBox  Grid.IsSharedSizeScope="True" 
                  ItemsSource="{Binding Variables}"
                  ItemTemplateSelector="{StaticResource templateSelector}">
        </ListBox>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
           <Button Content="Cancel" />
               <Button Content="Submit" 
                       Command="{Binding DataContext.CommitChangesCommand, 
                                   RelativeSource={RelativeSource FindAncestor, 
                                   AncestorType={x:Type TabControl}}}" />
        </StackPanel>
    </StackPanel>
</DataTemplate>
  </TabControl.ContentTemplate>
</TabControl>

我还需要扩展 future 控制可见性的变量数量,因为它还取决于它在应用程序中的使用位置。

最佳答案

您可以尝试 IMultiValueConverter 并使用 Multibinding。

<Window x:Class="ItemsControl_Learning.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:ItemsControl_Learning"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <local:VisibilityConverter x:Key="conv" />
</Window.Resources>
<Grid>
    <Button Content="Test">
        <Button.Visibility>
            <MultiBinding Converter="{StaticResource conv}">
                <Binding  Path="Role" />
                <Binding Path="OtherProp" />                   
            </MultiBinding>
        </Button.Visibility>
    </Button>
</Grid>

public partial class MainWindow : Window
{

    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new MainViewModel();
    }       
}

class MainViewModel
{
    private string role;
    public string Role
    {
        get { return role; }
        set { role = value; }
    }

    private string otherProp;
    public string OtherProp
    {
        get { return otherProp; }
        set { otherProp = value; }
    }
    public MainViewModel()
    {
        Role = "Admin";
        OtherProp = "Fail";
    }
}

class VisibilityConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (values[0].ToString().Equals("Admin") && values[1].ToString().Equals("Pass"))
        {
            return Visibility.Visible;
        }
        else
        {
            return Visibility.Collapsed;
        }
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Convert(...) 方法中,values 数组中不同输入的顺序与 MultiBinding.Bindings 中的顺序相同 集合。

在此示例中,values[0] 包含 Role 属性,values[1] 将是 OtherProp因为那是他们在 XAML 中插入的顺序

关于c# - 使用 ViewModel 中的多个变量绑定(bind) WPF 控制可见性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29974236/

相关文章:

wpf - 如何限制 <Border> 元素的宽度和高度等于其内部内容?

wpf - WPF 样式中 IsMouseOver 和 IsHighlighted 的区别

c# - 当比较字段是动态的时,如何与 List<T> 中的上一个或下一个元素的属性进行比较?

c# - 使 IEnumerator 以某种方式返回值的解决方法

c# - WPF .GetElementById() 方法

c# - 我如何在窗口栏中获得菜单?

c# - 如何为 DataGrid 设置透明背景?

c# - 为什么 Type.IsGenericType 对于没有通过方法反射获取返回类型的 Task 返回 TRUE,但 typeof(Task).IsGenericTyp 返回 FALSE

c# - 在 C# 中计算素数的最快方法?

c# - wpf 边框比标签大得多