ComboBox选择项目数据触发器以折叠子用户控件上的按钮

时间:2016-07-15 15:30:29

标签: c# wpf combobox triggers user-controls

我试图弄清楚如何让数据触发器在用户控件之间工作 - 在窗口和子用户控件(嵌入在窗口中的用户控件)之间,或者在具有子用户控件的用户控件之间。

按钮控件有5个按钮,但默认情况下第5个按钮是折叠的。当组合框项目" Fifth Button"选中我希望第四个按钮折叠,第五个按钮变为可见。如您所见,我将触发器设置为根据组合框选择更新主窗口上的Label。我在同一窗口中使用触发器没有问题,但我不知道如何让它们与嵌入在同一窗口中的用户控件进行通信。或者从一个控件到另一个控件。

@{
   var veh = ViewBag.Vehicles.Tolist(); 
   veh = veh.OrderBy(v => v.Name);
   var oldIndex = veh.FindIndex(v => v.Name == "Other");
   var item = veh[oldIndex];
   veh.RemoveItem(oldIndex);
   veh.Add(item);
} 

@foreach (Vehicle v in veh) {
      <input type="checkbox" name="VehicleId" value="@v.VehicleId"   id="@v.VehicleId" />
      <span for="@v.VehicleId">@v.Name</span><br /> 
}

我尝试使用ElementName,Path甚至relativeSource绑定按钮但是没有取得任何成功。我还尝试在控件的ButtonControl.Resources部分添加触发器。

<Window x:Class="ComboboxControlChange.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:ComboboxControlChange"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid Grid.Row="0">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition />
                </Grid.RowDefinitions>
                <ComboBox Grid.Row="0" x:Name="ButtonSelectCombobox" SelectedValuePath="Content" SelectedValue="{Binding ButtonSelection}" Height="24" Margin="150,0">
                    <ComboBoxItem x:Name="FirstButtonSelection" >First Button</ComboBoxItem>
                    <ComboBoxItem x:Name="SecondButtonSelection">Second Button</ComboBoxItem>
                    <ComboBoxItem x:Name="ThirdButtonSelection">Third Button</ComboBoxItem>
                    <ComboBoxItem x:Name="FourthButtonSelection">Fourth Button</ComboBoxItem>
                    <ComboBoxItem x:Name="FifthButtonSelection">Fifth Button</ComboBoxItem>
                </ComboBox>
                <StackPanel Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center" Orientation="Vertical">
                    <Label>You have selected button:</Label>
                    <Label HorizontalAlignment="Center">
                        <Label.Style>
                            <Style TargetType="{x:Type Label}">
                                <Setter Property="Content" Value=""/>
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding ElementName=FirstButtonSelection, Path=IsSelected}" Value="true">
                                        <Setter Property="Content" Value="One" />
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding ElementName=SecondButtonSelection, Path=IsSelected}" Value="true">
                                        <Setter Property="Content" Value="Two" />
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding ElementName=ThirdButtonSelection, Path=IsSelected}" Value="true">
                                        <Setter Property="Content" Value="Three" />
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding ElementName=FourthButtonSelection, Path=IsSelected}" Value="true">
                                        <Setter Property="Content" Value="Four" />
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding ElementName=FifthButtonSelection, Path=IsSelected}" Value="true">
                                        <Setter Property="Content" Value="Five" />
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </Label.Style>
                    </Label>
                </StackPanel>
            </Grid>            
        </Grid>
        <Grid Grid.Row="1">
            <local:ButtonControl />                            
        </Grid>
    </Grid>
</Window>



<UserControl x:Class="ComboboxControlChange.ButtonControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:ComboboxControlChange"
             mc:Ignorable="d" 
             d:DesignHeight="160" d:DesignWidth="517">
    <Grid Name="Link1MainGrid">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Button Grid.Column="0" VerticalAlignment="Center" Margin="5,0" >
            <TextBlock TextAlignment="Center">
                First<LineBreak/>Button
            </TextBlock>
        </Button>
        <Button Grid.Column="1" VerticalAlignment="Center" Margin="5,0">
            <TextBlock TextAlignment="Center">
                Second<LineBreak/>Button
            </TextBlock>
        </Button>
        <Button Grid.Column="2" VerticalAlignment="Center" Margin="5,0">
            <TextBlock TextAlignment="Center">
                Third<LineBreak/>Button
            </TextBlock>
        </Button>
        <Button Grid.Column="3" VerticalAlignment="Center" Margin="5,0" >
            <Button.Style>
                <Style TargetType="{x:Type Button}">
                    <Setter Property="Visibility" Value="Visible" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding ElementName=FifthButtonSelected, Path=IsSelected}" Value="true">
                            <Setter Property="Visibility" Value="Collapsed"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
            <TextBlock TextAlignment="Center">
                Fourth<LineBreak/>Button
            </TextBlock>
        </Button>
        <Button Grid.Column="3" Margin="4,4,4,50" Visibility="Collapsed">
            <Button.Style>
                <Style TargetType="{x:Type Button}">
                    <Setter Property="Visibility" Value="Collapsed" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding ElementName=FifthButtonSelected, Path=IsSelected}" Value="true">
                            <Setter Property="Visibility" Value="Visible"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>            
            <TextBlock TextAlignment="Center">
                Fifth<LineBreak/>Button
            </TextBlock>
        </Button>
    </Grid>
</UserControl>

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

这不起作用,因为窗口中的元素名称不在用户控件的范围内。 MSDN说:

  

[...]主要的XAML名称范围是在a的XAML根元素中定义的   单个XAML生产,并包含所有元素   包含在XAML的制作中。

实际上,这意味着当您为文件中的元素定义x:Name时,它只能在该文件中引用,并且在它之外是未知的。

另一种方法是在用户控件上创建Dependency Property,并将其用作在窗口和控件之间传递信息的方法。一个很好的副作用是,这会产生一些抽象,并允许更大的灵活性。

ButtonControl.xaml.cs:(将“功能”重命名为相关内容)

public partial class ButtonControl : UserControl
{
    ...

    public bool IsFeatureVisible
    {
        get { return (bool)GetValue(IsFeatureVisibleProperty); }
        set { SetValue(IsFeatureVisibleProperty, value); }
    }

    // Using a DependencyProperty as the backing store for IsFeatureVisible.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsFeatureVisibleProperty =
        DependencyProperty.Register("IsFeatureVisible", typeof(bool), typeof(ButtonControl), new UIPropertyMetadata(false));

    ...
}

现在你可以连接触发器来使用这个属性,但我们很幸运,在这种情况下,你正在处理布尔值和可见性,所以我们可以使它变得更简单:

<强> ButtonControl.xaml:

<UserControl x:Class="ComboboxControlChange.ButtonControl"
            x:Name="Myself"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
            xmlns:local="clr-namespace:ComboboxControlChange"
            mc:Ignorable="d" 
            d:DesignHeight="160" d:DesignWidth="517">

    <UserControl.Resources>
        <BooleanToVisibilityConverter x:Key="mBooleanToVisibilityConverter"/>
    </UserControl.Resources>

    <Grid Name="Link1MainGrid">

    ...

        <Button Grid.Column="3" VerticalAlignment="Center" Margin="5,0"  Visibility="{Binding ElementName=Myself, Path=IsFeatureVisible, Converter={StaticResource mBooleanToVisibilityConverter}}">
            <TextBlock TextAlignment="Center">
                Fourth<LineBreak/>Button
            </TextBlock>
        </Button>

        ...
    </Grid>
</UserControl>

最后,在Window中,我们需要在按钮控件的实例上为该属性提供一个值。我们可以在这里使用FifthButtonSelection元素名称,就像您在文件的其他部分一样:

<强> MainWindow.xaml

<local:ButtonControl IsFeatureVisible="{Binding ElementName=FifthButtonSelection, Path=IsSelected}"/>