问题
I have two Usercontrols say "Usercntrl1" and "Usercntrl2", "Usercntrl1" contains Slider, "Usercntr2" has ListBox with Images, Now when i change the Slider value in "Usercntrl1" ,the ListboxItems size(i.e,) Width and Height has to change with Respect to Slider value. It can be easily done when both of them present in same usercontrol as follows
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="1"/>
<Setter Property="BorderBrush" Value="Green"/>
<Setter Property="Width" Value="{Binding Path=Value, ElementName=sizeSlider, Mode=TwoWay}"/>
<Setter Property="Height" Value="{Binding Path=Value, ElementName=sizeSlider, Mode=TwoWay}"/>
<Setter Property="TabIndex" Value="1"/>
</Style>
</ListBox.ItemContainerStyle>
could somebody guide?
回答1:
If you really need to bind from one usercontrol to a property of another UserControl maybe you can use something like this:
Usercntrl1: Xaml:
<UserControl x:Class="ListBoxSliderSizeTest.Usercntrl1"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" x:Name="MainControl">
<Grid>
<Slider Maximum="200" Minimum="1" Value="{Binding ElementName=MainControl, Path=SliderSize, Mode=TwoWay}"/>
</Grid>
CodeBehind:
...
public double SliderSize
{
get { return (double)GetValue(SliderSizeProperty); }
set { SetValue(SliderSizeProperty, value); }
}
public static readonly DependencyProperty SliderSizeProperty =
DependencyProperty.Register("SliderSize", typeof(double), typeof(Usercntrl1), new PropertyMetadata(0.0));
...
UserCntrl2: XAML:
<UserControl x:Class="ListBoxSliderSizeTest.Usercntrl2"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" x:Name="MainControl">
<Grid>
<ListBox>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="1"/>
<Setter Property="BorderBrush" Value="Green"/>
<Setter Property="Width" Value="{Binding Path=SliderSize, ElementName=MainControl, Mode=OneWay}"/>
<Setter Property="Height" Value="{Binding Path=SliderSize, ElementName=MainControl, Mode=OneWay}"/>
<Setter Property="TabIndex" Value="1"/>
</Style>
</ListBox.ItemContainerStyle>
<Button/>
</ListBox>
</Grid>
CodeBehind:
---
public double SliderSize
{
get { return (double)GetValue(SliderSizeProperty); }
set { SetValue(SliderSizeProperty, value); }
}
public static readonly DependencyProperty SliderSizeProperty =
DependencyProperty.Register("SliderSize", typeof(double), typeof(Usercntrl2), new PropertyMetadata(0.0));
...
And then use this two Usercontrols:
<listBoxSliderSizeTest:Usercntrl1 x:Name="Usercntrl1"/>
<listBoxSliderSizeTest:Usercntrl2 Grid.Column="1" SliderSize="{Binding ElementName=Usercntrl1, Path=SliderSize}"/>
Edit:
so if Usercntrl1 hosts UserControl2 it looks like this:
Usercntrl1:
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Slider Maximum="200" Minimum="1" Value="{Binding ElementName=MainControl, Path=SliderSize, Mode=TwoWay}" x:Name="Slider"/>
<listBoxSliderSizeTest:Usercntrl2 Grid.Row="1" SliderSize="{Binding ElementName=MainControl, Path=SliderSize}" />
</Grid>
or:
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Slider Maximum="200" Minimum="1" x:Name="Slider"/>
<listBoxSliderSizeTest:Usercntrl2 Grid.Row="1" SliderSize="{Binding ElementName=Slider, Path=Value}" />
</Grid>
edit2:
Usercontrol1 XAML:
<Slider Maximum="200" Minimum="1" x:Name="Slider" Value="{Binding ElementName=MainControl, Path=SliderSize, Mode=TwoWay}" />
<TabControl x:Name="tc" Grid.Row="1"/>
Code behind:
var uc = new Usercntrl2();
var binding = new Binding("SliderSize") { Source = this,Mode = BindingMode.TwoWay};
uc.SetBinding(Usercntrl2.SliderSizeProperty, binding);
tc.Items.Add(uc);
回答2:
for your question in your last comment (apply the size only to the active item):
use a trigger:
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="True">
<Setter Property="Width" Value="{Binding Path=SliderSize, ElementName=MainControl, Mode=OneWay}"/>
<Setter Property="Height" Value="{Binding Path=SliderSize, ElementName=MainControl, Mode=OneWay}"/>
</DataTrigger>
</Style.Triggers>
or do you want apply it for all items in the active tab?
来源:https://stackoverflow.com/questions/17570070/how-to-change-listboxitem-size-with-respect-to-slider-value