Hey Dominique, thank your for the tips. I see where the problem is. Actually I don't have 'PreparePages' function...so the scale doesn't get any value and it doesn't work I guess. So I was thinking to add this function to MapPrinter loaded event. Please see the red words. But for some reasons the printExtent is always null. I put a breakpoint in this line: Envelope printExtent = mapPrinterWithDialog.PrintExtent....but it seems like there is no map in 'mapPrinterWithDialog' even I bind MyMap to its 'Map'. I am really confused...why the map is still empty after we bind its map property to MyMap, even in its loaded event? 
controls:MapPrinterDialog x:Name="MapPrinterDialog" Background="White" Width="350" Height="400" Style="{StaticResource MyMapPrinterDialogStyle}" Visibility="Collapsed" >
                <controls:MapPrinter x:Name="mapPrinterWithDialog" Map="{Binding ElementName=MyMap}" Style="{StaticResource WithLegend}" 
                                     Title="WIRT" Loaded="mapPrinterWithDialog_Loaded"/>
                <!--IsScaleFixed="True" Scale="2000000"-->
                <!--IsActive="{Binding ElementName=PrintBtn }"-->
            </controls:MapPrinterDialog>           
            <controls:MapPrinterIndicator MapPrinter="{Binding ElementName=mapPrinter}" />
private void mapPrinterWithDialog_Loaded(object sender, RoutedEventArgs e)
        {
            MapPrinter mapPrinterWithDialog = sender as MapPrinter;
            double mapHeight = MyMap.ActualHeight;
            double mapWidth = MyMap.ActualWidth;
            Envelope printExtent = mapPrinterWithDialog.PrintExtent;
            var mapSize = new Size(mapPrinterWithDialog.RotateMap ? mapHeight : mapWidth, mapPrinterWithDialog.RotateMap ? mapWidth : mapHeight);
            var mapUnit = mapPrinterWithDialog.MapUnits;
            bool isWebMercator = (mapPrinterWithDialog.Map != null && mapPrinterWithDialog.Map.SpatialReference != null &&
                                  (mapPrinterWithDialog.Map.SpatialReference.WKID == 102100 || mapPrinterWithDialog.Map.SpatialReference.WKID == 102113 || mapPrinterWithDialog.Map.SpatialReference.WKID == 3857));
            double ratioScaleResolution = RatioScaleResolution(mapUnit, printExtent.GetCenter().Y, isWebMercator);
            double scale = mapPrinterWithDialog.Scale;
            double printResolution;
            printResolution = Math.Max(printExtent.Width / mapSize.Width, printExtent.Height / mapSize.Height);
            scale = ratioScaleResolution * printResolution;
            if (scale != mapPrinterWithDialog.Scale)
                mapPrinterWithDialog.Scale = scale;
        }
        private static double RatioScaleResolution(MapUnit mapUnit, double yCenter, bool isWebMercator)
        {
            double ratio;
            int dpi = 96;
            double toRadians = 0.017453292519943295769236907684886;
            double earthRadius = 6378137; //Earth radius in meters (defaults to WGS84 / GRS80)
            double degreeDist = earthRadius * toRadians;// distance of 1 degree at equator in meters
            if (isWebMercator)
            {
                // Transform yCenter from web mercator to decimal degree
                yCenter = Math.Min(Math.Max(yCenter, -20037508.3427892), 20037508.3427892);
                var point = new MapPoint(0, yCenter);
                yCenter = point.WebMercatorToGeographic().Y;
                ratio = Math.Cos(yCenter * toRadians) * dpi * 39.37; // 39.37 = MapUnit.Meters/MapUnit.Inches
            }
            else if (mapUnit == MapUnit.DecimalDegrees || mapUnit == MapUnit.Undefined)
            {
                if (Math.Abs(yCenter) > 90)
                    ratio = 0.0;
                else
                    ratio = Math.Cos(yCenter * toRadians) * degreeDist * dpi * 39.37;
            }
            else
            {
                ratio = (double)dpi * (int)mapUnit / (int)MapUnit.Inches;
            }
            return ratio;
        }