Привязка свойства UserControl к его дочернему элементу через ElementName приводит к ошибке привязки - PullRequest
7 голосов
/ 20 февраля 2011

У меня есть следующий XAML:

<UserControl x:Class="WpfWindow.MyControl"
             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">
  <UserControl.RenderTransform>
    <TranslateTransform X="{Binding ElementName=MySlider, Path=ActualWidth}" />
  </UserControl.RenderTransform>
  <Grid>
    <Slider x:Name="MySlider" Canvas.Left="41" Canvas.Top="86" Height="23"  Width="100" Minimum="0" Maximum="100"/> 
  </Grid>
</UserControl>

Когда я пытаюсь использовать окно с UserControl внутри, я получаю:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=MySlider'. BindingExpression:Path=ActualWidth; DataItem=null; target element is 'TranslateTransform' (HashCode=53368240); target property is 'X' (type 'Double')

Это особенно странно, поскольку я использую тот же кодпрямо в окне работает безупречно.

На данный момент я решил проблему, установив привязку в коде, однако я понятия не имею, почему моя версия не работает, и я предпочел бы иметь все в XAMLесли возможно.

Спасибо!

Ответы [ 2 ]

8 голосов
/ 20 февраля 2011

Я заметил, что иногда при установке Bindings с ElementName на Window / UserControl и т. Д. Порядок объявления важен.Я не уверен в причине этого, но если вы объявите Grid до установки <UserControl.RenderTransform>, я думаю, что это будет работать

<UserControl ...>
    <Grid Background="Red">
        <Slider x:Name="MySlider" Canvas.Left="41" Canvas.Top="86" Height="23"  Width="100" Minimum="0" Maximum="100"/>
    </Grid>
    <UserControl.RenderTransform>
        <TranslateTransform X="{Binding ElementName=MySlider, Path=ActualWidth}" />
    </UserControl.RenderTransform>
</UserControl>
1 голос
/ 10 марта 2011

У меня действительно есть похожая проблема, и я хотел бы поделиться своим решением.

У меня есть набор шейдеров, которые я хочу применить к границам.Свойства шейдера, привязанные к значениям элемента управления (значение ползунка).

XAML:

<Window.Resources>
    <ResourceDictionary>
        <Shaders:BrightnessContrastEffect x:Key="brightnessContrastEffect" Contrast="{Binding ElementName=SliderContrast, Path=Value}" Brightness="{Binding ElementName=SliderBrightness, Path=Value}" />
        <Shaders:SaturationHueEffect x:Key="saturationHueEffect" Hue="{Binding ElementName=SliderHue, Path=Value}" Saturation="{Binding ElementName=SliderSaturation, Path=Value}"/>
        <Shaders:SharpenEffect x:Key="sharpenEffect" Amount="{Binding ElementName=SliderSharpen, Path=Value}" />
    </ResourceDictionary>
</Window.Resources>

...

<StackPanel Name="PanelImage" Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" SizeChanged="PanelImage_SizeChanged">
    <Border Effect="{StaticResource brightnessContrastEffect}">
        <Border Effect="{StaticResource saturationHueEffect}">
            <Border Effect="{StaticResource sharpenEffect}">
                <Border Name="PanelShaderInvert">
                    <Viewbox Stretch="Fill" MinHeight="400" MinWidth="640">
                        <dz:MultiScaleImage Name="ImageViolation" MinHeight="400" MinWidth="640"
                                            Source="{Binding ElementName=MyPath, Path=Content}"
                                            MouseLeftButtonDown="ImageViolationMouseLeftButtonDown"
                                            MouseLeftButtonUp="ImageViolationMouseLeftButtonUp"
                                            MouseRightButtonUp="ImageViolationMouseRightButtonUp" MouseMove="ImageViolation_MouseMove" />
                    </Viewbox>
                </Border>
            </Border>
        </Border>
    </Border>
</StackPanel>
<GridSplitter HorizontalAlignment="Right" VerticalAlignment="Stretch" Grid.Column="1" ResizeBehavior="PreviousAndNext" Width="0" />
<StackPanel Grid.Column="2" Grid.Row="0" Height="250" VerticalAlignment="Top">
    <Label Content="Brightness:" Style="{StaticResource DoubleLineLayoutLabel}" />
    <telerik:RadSlider Name="SliderBrightness" Minimum="-1" Maximum="1" Value="0" Margin="8,0" LargeChange="0.4" SmallChange="0.4" TabIndex="1" />
    <Label Content="Contrast:" Style="{StaticResource DoubleLineLayoutLabel}" />
    <telerik:RadSlider Name="SliderContrast" Maximum="2" Value="1" Margin="8,0" LargeChange="0.4" SmallChange="0.4" TabIndex="2" />
    <Label Content="Hue:" Style="{StaticResource DoubleLineLayoutLabel}" />
    <telerik:RadSlider Name="SliderHue" Maximum="359" Margin="8,0" LargeChange="72" SmallChange="72" TabIndex="3" />
    <Label Content="Saturation:" Style="{StaticResource DoubleLineLayoutLabel}" />
    <telerik:RadSlider Name="SliderSaturation" Maximum="5" Value="1" Margin="8,0" LargeChange="1" SmallChange="1" TabIndex="4" />
    <Label Content="Sharpen:" Style="{StaticResource DoubleLineLayoutLabel}" />
    <telerik:RadSlider Name="SliderSharpen" Maximum="2" Value="0" Margin="8,0" LargeChange="0.4" SmallChange="0.4" TabIndex="5" />
    <CheckBox Name="CheckBoxInvertColours" Content="Invert Colours" Margin="8" Checked="CheckBoxInvertColoursChecked" Unchecked="CheckBoxInvertColoursUnchecked" TabIndex="6" />
</StackPanel>

Прекрасно работает в Window, но после того, как япереместил этот XAML в пользовательский элемент управления, он просто перестал работать.

Вы не можете переместить Window.Resources в нижнюю часть пользовательского элемента управления.

Итак, решение, которое работает для меня, заключалось в назначении ресурсов.прямо в контейнере (в моем случае это Border) вместо ссылки на них из раздела Resource:

<StackPanel Name="PanelImage" Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" SizeChanged="PanelImage_SizeChanged">
    <Border>
        <Border.Effect>
            <Shaders:BrightnessContrastEffect Contrast="{Binding ElementName=SliderContrast, Path=Value}" Brightness="{Binding ElementName=SliderBrightness, Path=Value}" />
        </Border.Effect>
        <Border>
            <Border.Effect>
                <Shaders:SaturationHueEffect Hue="{Binding ElementName=SliderHue, Path=Value}" Saturation="{Binding ElementName=SliderSaturation, Path=Value}"/>
            </Border.Effect>
            <Border>
                <Border.Effect>
                    <Shaders:SharpenEffect Amount="{Binding ElementName=SliderSharpen, Path=Value}" />
                </Border.Effect>
                <Border Name="PanelShaderInvert">
                    <Viewbox Stretch="Fill" MinHeight="400" MinWidth="640">
                        <dz:MultiScaleImage Name="ImageViolation" MinHeight="400" MinWidth="640"
                                                                    Source="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=my:ImageControl, AncestorLevel=1}, Path=ImageSource}"
                                                                    MouseLeftButtonDown="ImageViolationMouseLeftButtonDown"
                                                                    MouseLeftButtonUp="ImageViolationMouseLeftButtonUp"
                                                                    MouseRightButtonUp="ImageViolationMouseRightButtonUp" MouseMove="ImageViolation_MouseMove" />
                    </Viewbox>
                </Border>
            </Border>
        </Border>
    </Border>
</StackPanel>
<GridSplitter HorizontalAlignment="Right" VerticalAlignment="Stretch" Grid.Column="1" ResizeBehavior="PreviousAndNext" Width="0" />
<StackPanel Grid.Column="2" Grid.Row="0" Height="250" VerticalAlignment="Top">
    <Label Content="Brightness:" Style="{StaticResource DoubleLineLayoutLabel}" />
    <telerik:RadSlider Name="SliderBrightness" Minimum="-1" Maximum="1" Value="0" Margin="8,0" LargeChange="0.4" SmallChange="0.4" TabIndex="1" />
    <Label Content="Contrast:" Style="{StaticResource DoubleLineLayoutLabel}" />
    <telerik:RadSlider Name="SliderContrast" Maximum="2" Value="1" Margin="8,0" LargeChange="0.4" SmallChange="0.4" TabIndex="2" />
    <Label Content="Hue:" Style="{StaticResource DoubleLineLayoutLabel}" />
    <telerik:RadSlider Name="SliderHue" Maximum="359" Margin="8,0" LargeChange="72" SmallChange="72" TabIndex="3" />
    <Label Content="Saturation:" Style="{StaticResource DoubleLineLayoutLabel}" />
    <telerik:RadSlider Name="SliderSaturation" Maximum="5" Value="1" Margin="8,0" LargeChange="1" SmallChange="1" TabIndex="4" />
    <Label Content="Sharpen:" Style="{StaticResource DoubleLineLayoutLabel}" />
    <telerik:RadSlider Name="SliderSharpen" Maximum="2" Value="0" Margin="8,0" LargeChange="0.4" SmallChange="0.4" TabIndex="5" />
    <CheckBox Name="CheckBoxInvertColours" Content="Invert Colours" Margin="8" Checked="CheckBoxInvertColoursChecked" Unchecked="CheckBoxInvertColoursUnchecked" TabIndex="6" />
</StackPanel>

Я считаю, что это ошибка, но по крайней мере есть обходной путь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...