【问题标题】:WPF converter implied in custom control?自定义控件中隐含的 WPF 转换器?
【发布时间】:2017-11-29 20:41:12
【问题描述】:

在我绘制饼图的 WPF 自定义控件中,我成功地让它绘制了一个给定字符串中的一组值的饼图,例如“10 20 30”将绘制一个具有正确比例的饼图。我将 DrawingImage 的绘图属性绑定到转换器以从字符串转换为 DrawingGroup。这很好用,但我试图绕过对转换器的需求。

这是我的主窗口:

<Grid Margin="10">

    <local:PieChart DrawingCode="289 666 1337 780" Width="400" Height="400" RingWidth="300" Background="White" />

</Grid>

这是我的自定义控件模板:

<Style TargetType="{x:Type local:PieChart}">
    <Setter Property="HorizontalContentAlignment" Value="Center" />
    <Setter Property="VerticalContentAlignment" Value="Center" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:PieChart}">
                <Grid>
                    <Image Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
                        <Image.Source>
                            <DrawingImage Drawing="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DrawingCode}" />
                        </Image.Source>
                    </Image>
                    <Ellipse Width="{TemplateBinding RingWidth}" Height="{TemplateBinding RingWidth}" Fill="{TemplateBinding Background}" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

最后,这是我对自定义控件类的尝试:

public class PieChart : Control
{
    public static readonly DependencyProperty DrawingCodeProperty = DependencyProperty.Register("DrawingCode", typeof(string), typeof(PieChart), new UIPropertyMetadata(null));
    public static readonly DependencyProperty RingWidthProperty = DependencyProperty.Register("RingWidth", typeof(double), typeof(PieChart), new UIPropertyMetadata(null));

    static PieChart()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(PieChart), new FrameworkPropertyMetadata(typeof(PieChart)));
    }

    public string DrawingCode
    {                                    
        get { return DrawingCodeConverter((string)GetValue(DrawingCodeProperty)); }
        set { SetValue(DrawingCodeProperty, value); }
    }

    public double RingWidth
    {
        get { return (double)GetValue(RingWidthProperty); }
        set { SetValue(RingWidthProperty, this.Width - value); }
    }

    public DrawingGroup DrawingCodeConverter(string value)
    {
        // This converter works but is long so I removed it from the post.
    }
}

我很确定问题出在我应该使用的数据类型中。另外,如果我不知道有完全不同的方法可以做到这一点,请告诉我。另请注意,RingWidth 不是问题,它是 DrawingCode。

【问题讨论】:

    标签: wpf binding custom-controls dependency-properties


    【解决方案1】:

    当在 XAML 中或通过 Binding、Style Setter、Animation 等访问属性时,可能会绕过依赖属性的 CLR 包装器的 getter 和 setter。WPF 然后直接调用 GetValue 和 SetValue。原因在XAML Loading and Dependency Properties中有解释

    因此,您不能在 getter 和 setter 中调用 GetValue 和 SetValue 以外的任何东西。相反,使用 PropertyChangedCallback 声明您的依赖属性,如下所示:

    public static readonly DependencyProperty DrawingCodeProperty =
        DependencyProperty.Register(
            "DrawingCode",
            typeof(string),
            typeof(PieChart),
            new FrameworkPropertyMetadata(DrawingCodePropertyChanged));
    
    public string DrawingCode
    {
        get { return (string)GetValue(DrawingCodeProperty); }
        set { SetValue(DrawingCodeProperty, value); }
    }
    
    private static void DrawingCodePropertyChanged(
        DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        var pieChart = (PieChart)o;
        pieChart.SetDrawingCode((string)e.NewValue);
    }
    
    private void SetDrawingCode(string drawingCode)
    {
        var drawingGroup = DrawingCodeConverter(drawingCode);
        // do something with drawingGroup 
    }
    

    【讨论】:

    • 我仍然有点困惑我应该如何绑定到这个以及我将逻辑放在 PieChart 控件中以从字符串转换为绘图组的位置。谢谢!
    • 您可以将用于将字符串转换为绘图组的代码放在 private void SetDrawingCode() { //Put Instance DrawingCode Property Changed code here DrawingCodeConverter(DrawingCode); }
    • 在您的示例中,您放置了 DrawingCodeConverter(DrawingCode) 但我的方法从字符串返回了一个 DrawingGroup。因此,如果我在 SetDrawingCode() 方法中获得了 DrawingGroup,那之后我该怎么办?抱歉所有问题,我只是在努力解决这个问题
    • private void SetDrawingCode() { DrawingGroup dg = DrawingCodeConverter(DrawingCode); }
    • 基本上,我该怎么做才能绑定到这个变量dg?
    猜你喜欢
    • 2017-07-19
    • 1970-01-01
    • 1970-01-01
    • 2016-06-22
    • 2011-03-13
    • 2011-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多